简体   繁体   English

使用 canActivate 的 Angular 和 RxJS 主题头痛

[英]Angular and RxJS Subject headache with canActivate

I got an example Angular2 project using firebase.我得到了一个使用 firebase 的示例 Angular2 项目。 The authService is using a method isAuthentificated with a subject, which returns the subject.asObserveable. authService 使用带有主题的 isAuthentificated 方法,该方法返回主题.asObserveable。

The method is called twice:该方法被调用两次:

  • in the header component constructor with subscribe and it passes the returned value to a variable在带有 subscribe 的头组件构造函数中,它将返回值传递给一个变量

  • In the router guard with first() in canActivate.在canActivate中使用first()的路由器守卫中。 The example project works as expected.示例项目按预期工作。

I reworte it without the FirebaseAPI with my own stuff and it works as expected in the header component, but in the router guard I always get an empty object back.我在没有 FirebaseAPI 的情况下用我自己的东西重写了它,它在标头组件中按预期工作,但在路由器保护中我总是得到一个空对象。 If I use it the way as in the example project, the router stops working, so I modified it, to see what happens.如果我按照示例项目中的方式使用它,路由器将停止工作,因此我对其进行了修改,看看会发生什么。 This is the code from the authService:这是来自 authService 的代码:

  isAuthenticated() {
const state = new Subject<boolean>();
state.subscribe(x => console.log('Subject start: ' + x));
this.localStorageService.observe('myToken')
  .subscribe((newToken: MyToken) => {
    console.log('localStorageCheck: ' + JSON.stringify(newToken));
    if ((newToken !== null) && (newToken.token !== '')) {
      state.next(true);
    } else {
      state.next(false);
    }
    console.log('state changed');
  });
state.subscribe(x => console.log('Subject subscribe: ' + x));
return state.asObservable();

} }

and this is the code of th guard:这是守卫的代码:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let pass: boolean = false;
const val = this.authService.isAuthenticated().first();
val.subscribe((x:boolean) => {
  console.log('Guard says: ' + x);
  pass = x;
});
// return val;
return pass;

} }

the example project just has: return this.authService.isAuthenticated().first();示例项目只有: return this.authService.isAuthenticated().first(); I can't see any difference in the logic and would like to understand, what I'm missing here.我看不出逻辑上有任何不同,并想了解我在这里遗漏了什么。

Thank you谢谢

ps.附: the code also working with the guard looks like this:与守卫一起工作的代码如下所示:

isAuthenticated() {
const state = new Subject<boolean>();
firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    state.next(true);
  } else {
    state.next(false);
  }
});
return state.asObservable();

} }

After some more testing I can observe, that canActivate runs as soon as the subject is updated in my project and this doesn't happen in the example project (although the subject is updated there as well).经过一些更多的测试,我可以观察到,只要我的项目中的主题更新, canActivate运行,而这不会发生在示例项目中(尽管主题也在那里更新)。 The only difference is that the Example uses the observer from Firebase and I use the one from ng2-webstorage.唯一的区别是示例使用来自 Firebase 的观察者,而我使用来自 ng2-webstorage 的观察者。 I can work around this of course by setting a private var outside canActivate and this works.我当然可以通过在 canActivate 之外设置一个私有变量来解决这个问题,这很有效。

I'd really like to understand the reason for this different bahaviour.我真的很想了解这种不同行为的原因。 Hope someone can elighten me, thanks.希望有人能给我启发,谢谢。

You can return not only boolean but Observable or Promise in canActivate method:您不仅可以在 canActivate 方法中返回布尔值,还可以返回 Observable 或 Promise:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.isUserAuthenticated.isAuthenticated();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM