【问题标题】:Why do Angular guards behave differently when using @select from @angular/redux-store为什么在使用 @angular/redux-store 中的 @select 时 Angular 防护的行为会有所不同
【发布时间】:2018-02-12 22:02:27
【问题描述】:
  • 我有一个使用两个保护的 Angular 设置。 canLoadcanActivate
  • 两者都通过@select从@angular-redux/store 获取相同的observable

问题:为什么canActivate@select 返回的observable 一起工作,而canLoad 从那时起会中断所有路由?这两个守卫有什么区别?

相关角度问题:https://github.com/angular/angular/issues/18991

auth.guard.ts

@Injectable()
export class AuthGuard implements CanLoad, CanActivate {

  @select() readonly authenticated$: Observable<boolean>; // @angular-redux/store

  canLoad(): Observable<boolean> | boolean {
    // return true; // works
    return this.authenticated$; // ERROR: all routing stops from and to the current page
  }

  canActivate(): Observable<boolean> | boolean {
    // return true; // works
    return this.authenticated$; // works
  }

}

app-routing.module

const routes: Routes = [
  {
    path: '',
    component: SomeAComponent,
    pathMatch: 'full'
  },
  {
    path: 'someb',
    component: SomeBComponent,
    canActivate: [
      AuthGuard
    ],
  },
  {
    path: 'lazy',
    loadChildren: './lazy/lazy.module#LazyModule',
    canLoad: [
      AuthGuard
    ]
  },
  {
    path: '**',
    redirectTo: '/'
  }
];

【问题讨论】:

  • canLoad() 保护用于组件而不是延迟加载模块时,它是否有效?我相信它与不加载 canLoad 路由的 RouterPreloader 相关联。来自router_preloader.d.ts 文件:` * 如果路由受到canLoad 守卫的保护,则预加载将不会加载它。 `
  • 我以为canLoad() 只用于延迟加载模块?在已经加载的模块上使用它时你会期望什么?
  • 如 github 问题中所述,应完成 observable。我不确定@select() readonly authenticated$. 是否完成。如果不是,take(1) 理论上不可能是我要找的东西,因为它不会让我从商店 (rxmarbles.com/#take) 获得最新更新。
  • 有道理,我并没有真正使用canLoad(),但这似乎有点奇怪
  • 你找到解决这个问题的方法了吗??我刚刚遇到了守卫工作正常的问题,但说当我在守卫路线时没有配置商店

标签: javascript angular redux observable


【解决方案1】:

我遇到了同样的问题,所以要解决它并让 CanLoad 和 CanActivate 都工作,你应该添加 operator take(1)

@Injectable()
export class AuthGuard implements CanLoad, CanActivate {

  @select() readonly authenticated$: Observable<boolean>; // @angular-redux/store

  canLoad(): Observable<boolean> | boolean {
    // return true; // works
    return this.authenticated$.pipe(take(1));
  }

  canActivate(): Observable<boolean> | boolean {
    // return true; // works
    return this.authenticated$; 
  }

}

【讨论】:

    【解决方案2】:

    我刚刚遇到了同样的问题,我认为这是 Angular 中的一个错误。我最终只是重写了我的守卫来存储一个通过订阅 Observable 填充的局部变量。我在这里使用ngrx/store。

    @Injectable()
    export class MustBeAuthenticatedGuard implements CanActivate, CanLoad {
    
      constructor(private store: Store<fromAuth.State>) {
        store.select(fromAuth.authenticated)
          .subscribe((authenticated) => {
            this.authenticated = authenticated;
          });
      }
    
      private authenticated: boolean
    
      canLoad(): boolean {
        return this.isAuthenticated();
      }
    
      canActivate(): boolean {
        return this.isAuthenticated();
      }
    
      private isAuthenticated() {
        if (!this.authenticated) {
          this.store.dispatch(new SignIn());
        }
        return this.authenticated;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 2015-08-23
      • 1970-01-01
      • 2020-11-19
      相关资源
      最近更新 更多