将CanActivate与LazyLoaded模块和Injectable一起使用

时间:2016-12-11 05:45:27

标签: angular angular2-routing angular2-services

我有一个身份验证服务,它在我的网站的管理员和用户部分都使用,但连接到后端API上的不同端点。我正在使用Factories根据加载的模块(admin vs user)提供不同的服务。

但是,当我尝试创建AuthGuard服务并注入我的AuthService时,它总是在路由器调用CanActivate时生成一个单独的AuthService实例。路由器是否在延迟加载模块的范围之外工作,这就是它生成新实例的原因?

auth.provider.ts

let AuthFactory = (
    http: Http,
    router: Router,
    storageService: StorageService,
    modalService: NgbModal,
    isAdmin: boolean
  ) => {
  return new AuthService(http, router, storageService, modalService, isAdmin);
};

export let AuthProvider = {
  provide: AuthService,
  useFactory: AuthFactory,
  deps: [ Http, Router, StorageService, NgbModal, IS_ADMIN ]
};

app.routing.ts

const appRoutes: Routes = [
  {
    path: 'mgmt',
    loadChildren: 'app/admin/admin.module'
  },
  { path: '',
    loadChildren: 'app/users/users.module'
  },
  { path: '**',
    redirectTo: ''
  }
];
@NgModule({
  imports: [ RouterModule.forRoot(appRoutes)],
  exports: [ RouterModule ]
})

export class AppRoutingModule {}

admin.routing.ts

RouterModule.forRoot(appRoutes);

const routes: Routes = [
  { path: '',
    component: AdminComponent,
    children: [
      {
        path: '',
        component: DashboardComponent,
        canActivate: [AuthGuard],
      {
        path: '**',
        redirectTo: ''
      }
    ]
  }
];

@NgModule({
  imports: [ RouterModule.forChild(routes)],
  exports: [ RouterModule ]
})

export class AdminRoutingModule {}

AUTH-guard.service.ts

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService,
              private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.authService.authenticated()
      .map(authenticated => {
        if (authenticated) {
          return true;
        } else {
          // do some other things
          return false;
        }
      })
      .take(1);
  }
}

1 个答案:

答案 0 :(得分:2)

由于AuthFactory的新用途,您每次都在构建一个新的AuthProvider。您应该转到“单例”设计模式,工厂提供构造函数,然后getter方法返回现有的AuthProvider或新的AuthProvider(如果它尚不存在)。这样你总是引用对象的单个实例。

查看有关在javascript中实现单例的大量资源。