2017-01-18 90 views
2

有沒有辦法避免組件中的行爲主體上的重複訂閱,而不是在ngOnDestroy中取消訂閱它?到目前爲止,這是我發現在導航組件中創建訂閱時避免重複訂閱的唯一方式。組件中的Angular 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(); 
    } 

} 

如果我導航多張時到部件,它會多次創建並銷燬。每次使用組件初始化時都會創建訂閱,並且必須使用組件銷燬訂閱。如果沒有,它將在下一個組件初始化時被複制...

有沒有辦法避免在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

你不應該'下一個'和'取消訂閱'。相反,只需:'complete' :) – Maxime