2016-09-12 9 views
4

canActivate()のためにObservable<boolean>リターンを使用しています。 次の関数はテストのために設定され、正しく解決され、コンポーネントが表示されます。角度2 CanActivateガードが作動しない

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { 
    return Observable.from([{ admin: true }]).map(x => 
    { 
    if (x.admin) return true; 
    return false; 
    }); 
} 

実際のコードの動作は、コンソール出力がルートをアクティブにする必要があるにもかかわらず、ログインコンポーネントにとどまることです。上のテストとの唯一の実際の違いは、Observable.fromの代わりにthis.auth.isAdmin()というサービスを呼び出すことです。 this.auth.isAdmin()の結果は、値がtrueのObservable<boolean>です。ここで

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { 
    const isAdmin$ = this.auth.isAdmin(); 
    return isAdmin$.map(x => 
    { 
    console.log('isAdmin returned ' + x); 
    if (!x) { 
     console.log('redirectToLogin'); 
     this.auth.redirectToLogin(state.url); 
     return false; 
    } else { 
     console.log('canActivate = true'); 
     return true; 
    } 
    }); 
} 

はルーティングです:ここでは

{ 
    path: 'admin', 
    canActivate: [AdminGuard], 
    children: [ 
    ...adminRoutes 
    ] 
}, 

は私のコンソール出力です:

isAdmin returned false 
admin-guard.service.ts:27redirectToLogin 
auth.service.ts:36 navigating to stored path "/admin" 
auth.service.ts:21 Object {isAdmin: true, isPaid: false, $key: "xYFs8kMDpKdYKxDw4AL21FtnSWn1"} 
admin-guard.service.ts:25 isAdmin returned true 
admin-guard.service.ts:31 canActivate = true 

そしてここでは、関心のある場合にはisAdmin()関数です

isAdmin(): Observable<boolean> { 
    if (!this.auth) return Observable.from([false]); 
    const uid = this.auth.uid; 
    return this.af.database.object(`user/${uid}`).do(x => console.log(x)).map(x => x.isAdmin); 
} 

答えて

7

isAdmin関数によって返された観測値は完了しません。 AngularFire2 FirebaseObjectObservableインスタンスは完了しません。基になるデータが変更されるとオブジェクトを放出します。

警備員によって返されたオブザーバブルは完了する必要があります。あなたは、最初の値が放出されたときに観察を完了するために、first(またはtake(1))を使用してこれを確保することができます:

canActivate(
    route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
): Observable<boolean> { 
    const isAdmin$ = this.auth.isAdmin(); 
    return isAdmin$.first().map(x => 
    { 
    console.log('isAdmin returned ' + x); 
    if (!x) { 
     console.log('redirectToLogin'); 
     this.auth.redirectToLogin(state.url); 
     return false; 
    } else { 
     console.log('canActivate = true'); 
     return true; 
    } 
    }); 
} 

を書いている時点で、それが完了するために返され、観察のために必要でした。ただし、Angularは返されたオブザーバブルでfirstを呼び出すため、オブザーバブルが完了する必要はなくなりました。

+0

おかげさまで、ありがとう! –

関連する問題