ユーザーがログインしているかどうかを基本的にチェックするログインガードがあります。ログインしている場合は、ログインをスキップしてホームページに移動します。私はこのコードを書きました、そしてこれはうまくいきます:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
map(isAuthenticated => {
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
さて、出力データ(isAuthenticated boolean)を変更または編集する必要がないので、私は考えました。まあ、なぜタップ演算子を使用しないのですか?だから、私は自分のコードを書き直します:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
HERE------> tap(isAuthenticated => { <------ HERE
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
それから私はChromeに行きました、そして、私は黒いページを見ました、そしてこれはそうでした:
いずれにしても、空白のページが表示されます。だから、私はデバッグに行きました、そして、それがif/elseブロックの中で正しくジャンプすることに気づきました...それで、なぜtap()がアプリを壊しているのですか?
これ はcanActivate
の署名です:
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
}
canActivate
はboolean
またはPromise
を返す必要があります。したがって、それをmap
してboolean
またはPromise
を返す必要があります。 tap
はトリックを行いません。
Angularガードメカニズムが機能するには、ガードcanActivate
が_Observable<boolean>
_を返す必要があります。
map
を使用すると、isAuthenticated
から得られるものとは異なる戻り値を定義できます。これにより、表示される内容が説明されます。
最初のバージョンではcanActivate
は実際に_Observable<boolean>
_を返します-2番目の場合はこのthis.store.select(fromApp.isAuthenticated).pipe(take(1))
を返しますが、おそらく望んでいるものではありません。