2016-03-24 5 views
1

angular.ioの例で触発されました(親と子はサービスを介して通信します)私は、ユーザが認証されたナビゲーションコンポーネントに通知するオブザーバ/観測パターンを実装しました。問題は、ユーザーがログアウトしたときにのみナビゲーションコンポーネントが通知を受け取ることです。オブザーバは、次のコールから値を受け取るだけです

export class AuthenticationService { 

    private isAuthenticatedSource = new Subject<boolean>(); 

    isAuthenticated$ = this.isAuthenticatedSource.asObservable(); 

    constructor(private http : AuthHttp) {} 

    login(email: string, password: string) { 
    ... 
    this.isAuthenticatedSource.next(true); 
    ... 
    } 

    logout() { 
    ... 
    this.isAuthenticatedSource.next(false); 
    ... 
    } 

} 

私は両方のコール(ログインとログアウト)が行われ、エラーがスローされていないことを保証しています

マイ認証サービスは次のようになります。私のナビゲーションコンポーネントは次のようになります:

export class NavigationComponent implements OnDestroy, OnInit { 

    private subscription: Subscription; 

    isAuthenticated: boolean; 

    constructor(private authService: AuthenticationService, 
       private router: Router) { 
    this.isAuthenticated = authService.isAuthenticated(); 
    } 

    logout(event) { 
    event.preventDefault(); 
    this.authService.logout(); 
    this.router.navigate(["Authentication", "Login"]); 
    } 

    ngOnDestroy() { 
    this.subscription.unsubscribe(); 
    } 

    ngOnInit() { 
    this.subscription = this.authService.isAuthenticated$.subscribe(
     value => console.log("updated to:", value) 
    ); 
    } 

} 

ログオン時にコンソールには「更新済み:true」とログアウト時に「Updated:false」が記録されます。問題は、ログアウト時にメッセージを表示するだけであるということです。明らかに、観察者はログイン時に値(真)を受け取っていません。あなたがなぜこれが起こっているのか説明するのを助けてくれることを願ってください。

更新

ログインするための呼び出しは、現在、以下に含まれています。ユーザーが(ログイン)フォームを送信すると、私のLoginComponentから呼び出されます。 <form (submit)="login($event)">

export class LoginComponent { 

    public email : string; 
    public password : string; 
    public errors : any; 
    public next : any; 

    constructor(private authService : AuthenticationService, 
       private router : Router, 
       private params : RouteParams) { 
    // default to navigate to dashboard on successfull login 
    let next = this.params.get("next") || "/Dashboard"; 
    this.next = [next]; 
    } 

    login(event) { 
    event.preventDefault(); 
    this.authService.login(this.email, this.password) 
         .subscribe(
         data => this.router.navigate(this.next), 
         errors => this.errors = errors); 
    } 

} 

対応するテンプレートは、ログインするための単一の呼び出しがあります。LoginComponentは次のようになります。ログインはアプリケーションの他の場所と呼ばれません。

+0

コンストラクタですでに購読することができます。コードが更新される入力に依存しない場合は、 'ngOnInit()'を待つ必要はありません。たぶん、イベントはすでに 'NavigationComponent'が購読される前に送られていたかもしれません。購読した直後に最後の値を取得するには 'BehaviorSubject'が必要だと思います。 –

+0

あなたのコードで 'login'への呼び出しが表示されません - あなたはSubjectにサブスクライブしたので、あなたはそれを呼び出していますか?サブジェクトはサブスクリプション後にのみサブスクライバにイベントを送信します。おそらく、別のタイプのサブジェクト、おそらく 'BehaviorSubject'が必要です。 – tddmonkey

+0

フィードバックありがとうございます。 Tried BehaviorSubjectとそれは何も変更されませんでした。私はコンストラクタへのsubscribeコールも移動しますが、状況は変わりません。 @tddmonkeyはい私は確信しています。 NavigationComponentがサブジェクトにサブスクライブした後、ユーザーがボタンをクリックするとログインが呼び出されます。 – ThaBird

答えて

0

私はそれが動作する理由excactlyわからないけど、静的変数としてisAuthenticatedSourceを設定する問題を修正します。理由を理解するためにもう少し調べなければなりません。ご意見をいただきありがとうございます。

2

私はどこにloginと呼ばれていません。しかし、UIを更新する前にサービスのログインを呼び出すと、UIが更新されていないという観察結果が再現されることを示すサンプルを作成しました。 AppComponentコンストラクタのauthService.login()呼び出しがUIに影響を与えないことを参照してください。これは、ngOnInitの後でサブスクライブが行われたためです。これが役に立つと願っています。

http://plnkr.co/edit/fteTLPCJUucCVKdVzJuP

export class AppComponent implements OnDestroy, OnInit { 

    @Output subscribe: string; 
    private subscription: Subscription; 
    private authService: AuthenticationService; 

    constructor(private authService: AuthenticationService) { 
    this.subscribe = 'not set'; 
    this.authService = authService; 

    authService.login('john', 'password'); // has no affect on UI since login happens before subscribe in ngOnInit 
    } 

    login() { 
    this.authService.login('john', 'password'); 
    } 

    logout() { 
    this.authService.logout(); 
    } 

    ngOnInit() { 
    this.subscription = this.authService.isAuthenticated$.subscribe(
     //value => console.log("updated to:", value) 
     value => this.subscribe = '' + value; 
    ); 
    } 

} 
+0

いい例。しかし、問題は依然として続きます。私はログインの呼び出しを含めるように私の質問を更新しました。ご覧のように、 'NavigationComponent'が購読した後に起こっています。 – ThaBird

関連する問題