2017-01-18 20 views
2

ngOnDestroyのサブスクリプション以外のコンポーネントのbehaviorSubjectに重複したサブスクリプションを避ける方法はありますか?これまでのところ、Observableでサブスクリプションを作成するコンポーネントを前後にナビゲートするときに、サブスクリプションの重複を避けるために見つけた唯一の方法です。コンポーネントの角2の重複したサブスクリプション

例:

ユーザーサービス

@Injectable() 
export class UserService { 

    constructor(private http: Http) { 
    this.setCurrentUser(); 
    } 

    private currentUser$ = new BehaviorSubject<User>(null); 

    public getCurrentUser(): Observable<User> { 
    return this.currentUser$.asObservable(); 
    } 
    public setCurrentUser(): void { 
    this.getLoggedUser(); // 
    } 


    private getLoggedUser(): void { 

    let getCurrentUserUrl = 'http://127.0.0.1:8000/users/current/' 

    let headers = new Headers({ 
     'Content-Type': 'application/json' 
    }); 
    let options = new RequestOptions({ 
     headers: headers 
    }); 
    options.withCredentials = true; 

    this.http.get(getCurrentUserUrl, options) 
     .map(this.toUser) 
     .catch(this.handleError) 
     .subscribe(
     user => this.currentUser$.next(user), 
     error => console.log("Error subscribing to currentUser: " + error) 
    ); 

    } 

    private toUser(res: Response): User { 
    let body = res.json(); 
    return body || { }; 
    } 

} 

およびユーザーサービスから観測可能に加入コンポーネント...

export class AppComponent implements OnInit, OnDestroy { 

    currentUserSubscription:any; 

    constructor(
    private userService:UserService, 
    private authentificationService:AuthenticationService 
) {} 

    user:User; 

    ngOnInit() { 
    this.currentUserSubscription = this.userService.getCurrentUser().subscribe(
     data => { 
     this.user = data; 
     console.log('Main : ', this.user); 
     } 
    ); 
    } 

    ngOnDestroy() { 
    // I want to avoid writing this for every subscription 
    this.currentUserSubscription.unsubscribe(); 
    } 

} 

私はコンポーネントにmulitple時間を移動すると、作成され、複数回破壊されます。サブスクリプションは、コンポーネントの初期化とともに作成され、コンポーネントで破棄する必要があります。そうでない場合は、次のコンポーネントの初期化時に複製されます。

ngOnDestroyでサブスクリプションを削除する方法はありますか?

答えて

3

一度購読したい場合は、テンプレート上で非同期パイプを使用する必要があります。非同期パイプは、サブスクリプションを自動的に管理します。この方法が賢明な場合は、スマートコンポーネントとプレゼンテーションコンポーネントでアプリケーションを作成する必要があります。これをチェックするanswer

サブスクリプションをサブスクライブ解除する別の方法は、サブジェクトが値を送信するまでサブスクリプションが完了するようにすることです。あなたは常に購読を停止するか、メモリリークが発生します。

export class AppComponent implements OnInit, OnDestroy { 

    currentUserSubscription:any; 

    constructor(
    private userService:UserService, 
    private authentificationService:AuthenticationService, 
    private _destroy : Subject() = new Subject(); 
) {} 

    user:User; 

    ngOnInit() { 
    this.currentUserSubscription = this.userService.getCurrentUser() 
    .takeUntil(this._destroy) 
    .subscribe(
     data => { 
     this.user = data; 
     console.log('Main : ', this.user); 
     } 
    ); 
    } 

    ngOnDestroy() { 
    this._destroy.next(); 
    this._destroy.unsubscribe(); 
    } 

} 
+0

ありがとう! 「破壊されるまで」の解決策は、私が探していたものでした。私は、被験者がどのように宣言され、初期化されたかについていくつかの調整を加えなければならなかったが、それは機能する。 私はスマートなプレゼンテーションコンポーネントの概念を見ていきます。 –

+0

あなたは 'next'と' unsubscribe'をしてはいけません。代わりに、単に: 'complete' :) – Maxime

関連する問題