2017-03-24 5 views
0

Ich habe einen Betreff Service wie folgt;Angular 2 abonnieren nach Tab ändern und erneut besuchen

private subject = new Subject<any>(); 

sendMessage(message: any) { 
    this.subject.next(message); 
} 

clearMessage() { 
    this.subject.next(); 
} 

getMessage(): Observable<any> { 
    return this.subject.asObservable(); 
} 

und Fütterung der Nachricht von Stammkomponente

HINWEIS: Meine Eltern-Kind-Komponenten verbunden über router-outlet

private getMerchantDetail() { 
let data = { 
    Id: this.merchantId, 
} 
this.merchantsService.getMerchants(data) 
    .then((res) => { 
    // console.log(res) 
    if (res.Success) { 
     this.merchant = res.Data[0]; 
     this.merchantListDetailService.sendMessage(res.Data[0]); -> here 
    } 
    }) 
    .catch((err) => { }) 
} 

Und dann die Daten von allen untergeordneten Komponenten zeichnen;

ngOnInit() { 
    this.merchantSubscribe = this.merchantListDetailService.getMessage() 
     .subscribe(merchant => { 
     console.log(merchant) 
     this.merchant = merchant; 
     this.getMerchantPaymentChannels(); 
     }) 
    } 

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

PROBLEM: Alles ist gut, wenn man von Kind Komponenten zunächst auf neu geladene Seite geöffnet. Wenn ich jedoch die Registerkarte meiner untergeordneten Komponenten änderte und die ursprünglich geöffnete untergeordnete Komponente erneut besuchte, wurden die abonnierten Daten nicht abgerufen. Aber ngOnInit Funktion funktioniert wieder. Auch getMessage() in service funktioniert auch. Nur der Rückruf der untergeordneten Komponente subscribe ruft die Daten nicht erneut ab.

Antwort

0

Ich denke, dass Sie eine Funktion innerhalb Ihres Kindes Komponente benötigen, die auch die getMessage in Service-Anrufe oder müssen Sie die Nachricht oder Daten zu übergeben, die Sie von Stammkomponente

1

Dies ist eine etwas über @Input Dekorateur bekam alte Frage, aber ich stieß auf das gleiche Problem. Was ich getan habe, um dies zu beheben, war die Verwendung von BehaviorSubject anstelle von Subject. Mein Verständnis ist, dass BehaviorSubject den zuvor eingestellten Wert "erinnert", aber Subject nicht.

Wenn Sie einen Betreff abonnieren, hört er nur auf Änderungen zu, aber wenn es keine gibt, wird nichts passieren. Wenn das übergeordnete Element den nächsten Wert für den Betreff festlegt, sendet es die Nachricht, behält jedoch keine Informationen darüber, was es gesendet hat. Und da Sie nur Tabulatoren verwenden, sendet dieser Elternteil es einmal und das war's. Ihr Kind erhält die erste "Änderung", aber da sich beim Ändern der Registerkarten nichts ändert, wird keine weitere Nachricht gesendet.

Es gibt eine sehr starke Möglichkeit, dass ich missverstanden habe, wie das alles funktioniert, aber der einzige wirkliche Unterschied, den ich machen musste, als ich von Subject zu BehaviorSubject ging, war ein Anfangswert für das BehaviorSubject.

private subject = new BehaviorSubjectSubject<any>(''); 

sendMessage(message: any) { 
    this.subject.next(message); 
} 

clearMessage() { 
    this.subject.next(''); 
} 

getMessage(): BehaviorSubject<any> { 
    return this.subject; 
} 

Außerdem änderte ich den Rückgabetyp zu BehaviorSubject und entfernte die asObservable.

Wenn das untergeordnete Element initialisiert wird, hat es einen leeren Wert (oder was auch immer Sie dieses ursprüngliche BehaviorSubject festlegen), aber wenn das übergeordnete Element den nächsten Wert festlegt, wird die Änderung übernommen und BehaviorSubject behält den Wert ebenfalls bei. Wenn Sie Tabulatoren ändern, wird es immer wieder auf diesen Wert zurückgesetzt.

Ich weiß nicht, ob es Nachteile gibt, die dazu kommen, aber es scheint jetzt gut für mich zu funktionieren. Ich werde aktualisieren, wenn sich das ändert oder wenn ich einen besseren Weg finde.

Verwandte Themen