2017-01-15 4 views
2

Hat jemand, warum dieser Code (Initialisierung eines Wertes von Subject) nicht funktioniert? Gibt es einen Fehler oder ein Design? Was mache ich falsch?Subject.next feuert nicht in ngOnInit

ts

import { Component, OnInit } from '@angular/core'; 
import { Subject } from "rxjs"; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.styl'] 
}) 
export class AppComponent implements OnInit { 
    itemSupplier$: Subject<any[]> = new Subject<any[]>(); 

    items: any[] = [ 
    {name: 'Item 1', value: 'item1'}, 
    {name: 'Item 2', value: 'item2'}, 
    ]; 

    ngOnInit(){ 
    this.itemSupplier$.next(this.items); 
    } 
} 

html

<ul> 
    <li *ngFor="let item of itemSupplier$ | async">{{item.name}}</li> 
</ul> 
+2

Könnten Sie auf * "funktioniert nicht" * erweitern? – jonrsharpe

Antwort

3

Es scheint wie ein Timing-Problem, es funktioniert, wenn Sie es in einem setTimeout werfen.

setTimeout(() => this.itemSupplier$.next(this.items), 0)

EDIT

Es ist eigentlich eine bessere Idee BehaviorSubject zu verwenden. Dies liefert den letzten Wert, wenn es abonniert ist.

+0

Ja, tatsächlich habe ich es gleich nach dem Stellen meiner Frage entdeckt, aber es ist mir immer noch nicht klar, warum ich in diesem speziellen Fall auf 'setTimeout' zurückgreifen sollte. – user776686

+0

Ich habe es eckig getestet, und es sieht so aus, als ob die asynchrone Pipe das Abonnement erst NACH ngOnInit registriert, also rufst du als nächstes an, ohne dass es abonniert ist. – Steveadoo

+0

Oh, danke für deine Mühe! Glauben Sie, dass es angular oder rx Team als Bug gemeldet werden sollte? Oder sollte ich stattdessen AfterInit verwenden? – user776686

0

Ich hatte das gleiche Problem und setTimeout war als Lösung wirksam, aber festgestellt, dass ich setTimeout nicht verwenden musste, wenn ein Observable, dem die switchMap() - Methode des Subjekts zugewiesen wurde, vor dem nächsten Aufruf abonniert wurde (). In Ihrem Beispiel könnte es erforderlich sein, ein Observable zu erstellen, die Eigenschaft direkt zu abonnieren und zu aktualisieren, anstatt die asynchrone Pipe zu verwenden.

0

Sie könnten Ihren nächsten Anruf in den AfterViewinit-Hook machen. Die asynchrone Pipe wird in diesem Moment zu dem Betreff abonniert.