2017-02-16 4 views
1

ich nach einem Weg suchen eine loading bar component auf einem observable stream zu benutzen?Angular 2: Ladebalken Komponente mit beobachtbaren Strömen

Ich habe eine component, die Daten von observable unter Verwendung der async pipe anzeigt. Dieses Observable kann auch die Daten manipulieren, z. B. mit map.

Zur Zeit habe ich diese in der Komponente:

this.listData$ = this.http.get('/itemList') 
      .map(data => this.manipulate(data)) 

und in Vorlage:

{{listData$ | async}} 

Der Server die Daten als empty [] zurückkehren kann, 'unavailable' oder array von Elementen.

Wie kann ich in den Strom tippen und eine Ladekomponente zuzuführen, die eine Ladebalken angezeigt werden würde, wenn die Daten geladen werden, und Fehlermeldungen anzeigen, wenn sie leer oder nicht verfügbar ist? Etwas nach dem Vorbild von ...

this.listData$ = this.http.get('/itemList') 
       //.something here?? 
       .map(data => this.manipulate(data)) 


<loading-bar [data]='listData$' [noDataMsg]='"no data"' [errorMsg]='unavailable'> 
    {{listData$ | async}} 
</loading-bar> 

Im Idealfall würde Ich mag die async pipe halten mit und zeichne nicht in meiner Komponente. Aber wenn man das Observable an die Ladebalken-Komponente übergibt und dort einträgt, macht das 2 http calls ... dann muss ich. share() auf dem Observable ...

Welchen Ansatz nehmen Sie zum Laden, keine Daten und Fehlermeldungen mit Ihren Streams anzeigen?

+0

Eigentlich können Sie einige 'loading' Flag verwenden und nach innen zu wahren, bevor http und auf false gesetzt 'map' wenn Sie nicht abonnieren möchten. So kann Ihr Laden "loading" Variablenstatus – VadimB

+0

hören Sie können 'do' Operator verwenden, ermöglicht es Ihnen, eine Operation ohne Verwendung von map, wie' this.http.get (...) hinzuzufügen. Do (loading = false). map (... => ...); ' – Supamiu

Antwort

1

Ihre Idee der beobachtbare zu <loading-bar> scheint zu passieren.

Wenn Ihre einzige Sorge mehrere Abonnements zu vermeiden ist, haben Sie zwei Möglichkeiten:

1. Teilen Sie die ursprüngliche beobachtbaren

this.listData$ = this.http.get('/itemList') 
        .map(data => this.manipulate(data)) 
        .share(); 

2. Erstellen Sie einen Vermittler BehaviorSubject

Das Subjekt wird als ein "Puffer" zwischen dem ursprünglichen Observablen und der Vorlage wirken:

  • Sie Rohr die Werte der ursprünglichen obs in Ihre BehaviorSubject.
  • Ihre Vorlage abonniert (über async) zu Ihrem BehaviorSubject.

Es kann immer noch mehrere Abonnements von der Vorlage geben, aber sie sind zu Ihrem Thema. Das ursprüngliche Observable wird jedoch nur EINMAL von Ihrem Betreff abonniert (was bedeutet, dass die HTTP-Anfrage nur einmal ausgeführt wird).

Der Code würde in etwa so gehen (ich habe es nicht getestet):

In der Klasse:

this.listDataBuffer$ = new BehaviorSubject<any>(null); 
this.listData$.subscribe(listDataBuffer$); 

In der Vorlage:

{{listDataBuffer$ | async}} 

ZUSÄTZLICHE HINWEISE:

  1. Sie sagten, Ihre ursprüngliche Observable emittiert eine Reihe von Elementen. Dies bedeutet, dass es sich um eine binäre Operation handelt: entweder haben Sie ALLE Elemente oder Sie haben KEINE. Mit dieser Konfiguration können Sie nie Fortschritt anzeigen. Sie können nur zwischen zwei Status wechseln, "Laden" und "Fertigstellen".

  2. Keine Notwendigkeit [ ] um Ihre Eingaben zu verwenden, wenn Sie Stringliterale vorbei sind:

// YOUR CODE: 
<loading-bar [noDataMsg]='"no data"' [errorMsg]='"unavailable"'> 

// COULD BE: 
<loading-bar noDataMsg="no data" errorMsg="unavailable"> 
+0

Merci! Das scheint ein guter Ratschlag zu sein, ich werde diese Konzepte später noch einmal ausprobieren und darüber berichten. – Thibs

+0

Sieht man sich das genauer an: this.listDataBuffer $ = new BehaviorSubject (null); this.listData $ .subscribe (listDataBuffer $); Bedeutet das nicht, dass ich listData $ in onDestroy abbestellen muss? Ich nehme an, dass die Verwendung von .share() weniger lästig ist, als ein Thema zu erstellen und sich um das Abmelden zu sorgen, oder fehle ich etwas? Danke nochmal – Thibs

+0

Du hast vollkommen recht. Gemäß http://stackoverflow.com/a/40819423/1153681. Rückblickend scheint meine Lösung übertrieben zu sein, ich werde meine Antwort entsprechend aktualisieren. – AngularChef

Verwandte Themen