2017-10-10 1 views
0

Ich habe eine Komponente, in der ich eine Tabelle von Daten (Benutzer) angezeigt von einer http-Anfrage an eine API generiert. Es gibt eine Vielzahl von Filtern auf den Tisch, I die Tabellendaten zu erzeugen, wie folgt:Refreshing Liste mit CombineLatest: Angular2 + RxJS

this.displayUsers$ = Observable.combineLatest(
      this.users$, 
      this.siteFilter$, 
      this.clientFilter$, 
      this.activeFilter$, 
      this.nameFilter$ 
     ) 
      .map(([users, siteFilter, clientFilter, activeFilter, nameFilter]) => { 
       console.log("Users changed? ", users); 
       if (siteFilter === null 
        && clientFilter === null 
        && activeFilter === null 
        && nameFilter.length < 1) { 
        return users; 
       } 
       return users 
        .filter(user => { 
         // manipulate users array based on filters 
        }) 
      }); 

Die xFilter$ s BehaviorSubjects sind, die an ihren Eingängen in der Vorlage neue Werte in Abhängigkeit von Änderungen emittieren. users$ wird wie folgt vergeben:

this.users$ = this.userService.getList(); 

Wo getList() eine HTTP-Anforderung gibt eine Liste von Benutzern zu erhalten.

Die Liste wird erfolgreich aktualisiert, wenn die Filter geändert werden, aber ich habe Probleme, wenn ich die Liste mit neuen Benutzern aktualisieren muss. Zum Beispiel kann ein Benutzer CRUD-Operationen in der Tabelle der Benutzer ausführen (dh einen Benutzer löschen). Wenn der Benutzer gelöscht wird, wird die Tabelle jedoch nicht aktualisiert, um diese Änderung wiederzugeben. Die Methode, die ich gerade bin mit (versuchen) zu frisch ist die Tabelle durch eine Refresh-Funktion für den Erfolg Rückruf des Löschvorgangs aufrufen:

refreshUserList() { 
     console.log("Refreshing user list"); 
     this.users$ = this.userService.getList(); 
    } 

Trotz dieser nach der Operation Aufruf abgeschlossen ist, die combineLatest beobachtbare nicht wieder 'ausgelöst' und die Listendaten bleiben veraltet. Gibt es eine bessere Möglichkeit, die von combineLatest generierten Daten mit HTTP-Anfragen zu aktualisieren?

Antwort

1

Das Hauptproblem besteht darin, dass im Falle der Aktualisierung der Benutzerliste $ beobachtbare Benutzer keinen neuen Wert ausgibt. Du musst es so machen.

Dies ist Skelett einer Idee wie man es beheben:

const updateUsersTrigger = new Subject<void>(); 

this.displayUsers$ = Observable.combineLatest(
    // switchMap() will re-subscribe to this.userService.getList() observable on each emit from updateUsersTrigger 
    // thus making http requests each time when user list should be updated. 
    updateUsersTrigger.startWith(null).switchMap(() => this.userService.getList()), 
    this.siteFilter$, 
    this.clientFilter$, 
    this.activeFilter$, 
    this.nameFilter$ 
) 
    .map(([users, siteFilter, clientFilter, activeFilter, nameFilter]) => { 

    ....... 

}); 

// this will trigger user list update 
updateUsersTrigger.next(); 
+0

Das macht sehr viel Sinn, danke für den Vorschlag. Ich denke jedoch, dass ich etwas mit meiner Implementierung vermisse, weil ich jetzt keine Tabellendaten bekomme (auch wenn ich Filter ändere). Ich habe RefreshUserList() geändert {updateUsersTrigger.next(); } und nenn das in ngOnInit(), aber immer noch kein Glück. – natmegs

+0

@natmegs, versuchen Sie etwas wie folgt: 'updateUsersTrigger.startWith (null) .switchMap (() => ... Anruf Service ...)' anstatt etwas in ngOnInit() - ich würde nicht erwarten, dass es funktioniert eigentlich denke ich, dass es zu früh feuert. –

0

Ich bin nicht in der Lage noch zu kommentieren, also werde ich hier schreiben und mich korrigieren, wenn ich falsch oder wenn dies aus ist die Frage. Wenn Sie bei erfolgreichem Löschen .splice() verwenden, um das DOM zu aktualisieren, anstatt eine weitere HTTP-Anforderung zu senden, wäre das nicht einfacher und weniger anstrengend für den Client?

+0

In jedem Fall benötigt OP etwas Observable, um ein neues Array zu senden, sei es http-Anfrage oder splice() Ergebnis in einigen Observable.map() oder etwas anderes. –