2016-11-06 5 views
9

zbudować usługę dialogowe potwierdzenia prosty (kątowa 2) za pomocą tej metody:Czy Subject.complete() anuluje subskrypcję wszystkich odbiorców?

confirm(body?: string, title?: string): Subject<void> { 
    this.confirmation = new Subject<void>(); 
    // ... show dialog here... "are you sure?" 
    return this.confirmation; 
} 

_onYesClicked() { 
    // ... closing the dialog 
    this.confirmation.next(); 
    this.confirmation.complete(); 
} 

_onNoClicked() { 
    // ... closing the dialog 
    this.confirmation.complete(); 
} 

Zastosowanie:

confirmationService.confirm().subscribe(() => alert("CONFIRMED")); 

Jeśli ktoś korzysta z usługi, dostaje Subject (który jest zauważalny) powrócił i może "subskrybować()" do niego. Subskrypcja jest wywoływana po kliknięciu "Tak", a zatem potwierdzenie zostało udzielone ...

Czy to jest właściwy sposób? I ważniejsze ... będzie wywołanie

this.confirmation.complete(); 

wypisać subskrybowanych słuchaczy, a tym samym uniknąć odniesień garki (wycieków pamięci)?

+0

Edytowałem tytuł, ponieważ metoda 'complete()' nie jest częścią interfejsu Obervable. –

Odpowiedz

13

Jeśli chcesz mieć pewność, że usuwa on wszystkie obserwatory, możesz to sprawdzić samodzielnie pod numerem https://github.com/ReactiveX/rxjs/blob/master/src/Subject.ts#L82. Wywołuje on complete() we wszystkich obserwatorach (obserwatorami są zazwyczaj tylko głupie obiekty implementujące Observer interface), a następnie ustawia this.observers.length = 0;. Tak więc odpowiedź brzmi "tak".

Twoje podejście jest prawidłowe, w zasadzie jest takie samo, jak Angular2 regularnie ma z EventEmitter. Jedną rzeczą, którą możesz poprawić, jest rozpoczęcie korzystania z asObservable() przy wystawianiu Subject s. Spowoduje to ukrycie faktu, że używasz pod spodem funkcji Subject i zwraca tylko zwykłą obserwowalną. W ten sposób nie pozwolisz swoim użytkownikom przypadkowo (lub z powodu nieporozumień) próbować zadzwonić pod numer next(), complete() lub error() na swoim Subject.

Jeśli chodzi o wycieki pamięci, musi to być obsługiwane przez RxJS, więc nie należy się tym przejmować, a jeśli wystąpi problem, autorzy prawdopodobnie zauważyliby to przed tobą.

+0

Wywołałbym również funkcję error() zamiast complete(), gdy użytkownik kliknie Nie. Albo użyłbym obietnicy, a nie obserwowalnej. To jest BTW, co robią modemy ng-bootstrap. –

+0

Hehehe ... to geniusz, tylko patrząc na źródło - to sprawia, że ​​na pewno czuję się pewna, że ​​nie ma żadnych odniesień. Również świetna porada na temat "asObservable()" - Dziękujemy! – Wolfgang

+0

@JBNizet Myślę, że kliknięcie "Nie" nie musi oznaczać błędu, ale jest to pytanie do OP nie dla mnie, myślę. – martin

Powiązane problemy