如何在lazyloading中避免路由器保护服务中的重复调度操作?

时间:2018-02-26 07:31:24

标签: angular ngrx

我正在使用NgRx存储进行身份验证,我的问题在于路由及其子级。我正在使用的防护是用于角色身份验证,同时我通过调度IsAuthenticated操作检查用户是否仍在服务器上进行身份验证。 当我访问子路线时,问题开始,警卫两次开火,一次为父母,另一次为孩子!如何避免此重复操作调度?我尝试了.take(1),但它允许动作只被触发一次,然后完全被忽略。

这是我的警卫服务代码的快照,

@Injectable()
export class RoleGuardService implements CanActivate {
  constructor(private store: Store<fromApp.AppState>, private router: Router) {
  }
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean {
    this.store.dispatch(new authActions.IsAuthenticated(fromAuth.authId));
    let isInRole = false;
    let isAuth: boolean;
    let userDashboardUrl: string;
    let userRoles: string[];
    this.store.select(c => c.auth.entities[fromAuth.authId]).subscribe(
      (data: Auth) => {
        isAuth = data.authenticated;
        userRoles = data.userData.roles;
        userDashboardUrl = data.userData.dashboardUrl;
      });
    const expectedRole: Array<string> = (route.data.expectedRole['roles']).map(
      (roles) => {
        return roles.toUpperCase();
      }
    );
    if (userRoles) {
      userRoles = (userRoles).map(
        (data) => {
          return data.toUpperCase().substring(0, data.length - 1);
        }
      );
      isInRole = expectedRole.some(r => userRoles.indexOf(r) !== -1);
    } else {
      isInRole = false;
    };

     if (! isAuth) {
       this.store.dispatch(new authActions.Logout(fromAuth.authId, fromAuth.invalidAuth, state.url));
    }
     if ( isAuth && ! isInRole ) {
      this.router.navigate([userDashboardUrl]); // redirect to user dashboard
    }
     return isInRole;
  }
}

我的父路线,

const dbRoutes: Routes = [

    {
      path: '', component: DbHomeComponent, data: { preload: true }, children: [
        {
          path: 'registry',
          canActivate: [RoleGuardService],
          data: { expectedRole: { roles: ['reg'] } },
          loadChildren: 'app/core/database/database-cores/registry-core/modules/registry.module#RegistryModule',
      }, .....

然后是子路线,

const routes: Routes = [

    { path: '', component: RegistryOutletComponent, children: [
        {path: '', component: DashboardComponent},
        {
            path: 'patientregistration',
            component: PatientRegistrationFormComponent,
            canActivate: [RoleGuardService],
            data: { expectedRole: { roles: ['reg5','reg4'] } },
        },
    ]},
];

和我的副作用,

 @Effect()
  onIsAuthenticatedUser = this.actions$
    .ofType(AuthActions.ISAUTHENTICATED)
    .map((action: AuthActions.IsAuthenticated) => { return action })
    .switchMap((action: AuthActions.IsAuthenticated) => {
      const actionPayload = action;
      return this.httpService.getRequest('Account/IsAuthenticated')
        .catch(() => { return Observable.empty() })
        .switchMap((isAuth: HttpResponse<boolean>) => {
          if (!isAuth.body) {
            return Observable.of(new AuthActions.Logout(fromAuth.authId, fromAuth.invalidAuth, actionPayload.returnUrl));
          } else {
            return Observable.concat(
              Observable.of(new AuthActions.Authenticated(fromAuth.authId, this.fetchUserData()),
            ),
             Observable.empty());
          }
        });
    });

这里我注意到了这个问题,

Duplicate action

0 个答案:

没有答案