2017-10-10 6 views
0

J'ai un composant dans lequel j'affiche un tableau de données (utilisateurs) généré à partir d'une requête http vers une API. Il existe une variété de filtres sur la table, donc je produis les données du tableau comme suit:Rafraîchir la liste en utilisant 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 
        }) 
      }); 

Les xFilter$ s sont BehaviorSubjects qui émettent de nouvelles valeurs en réponse aux changements à leurs entrées dans le modèle. users$ est affecté comme suit:

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

getList() retourne une requête http pour obtenir une liste d'utilisateurs.

La liste est mise à jour avec succès chaque fois que les filtres sont modifiés, mais j'ai des problèmes lorsque je dois mettre à jour la liste avec de nouveaux utilisateurs. Par exemple, un utilisateur peut effectuer des opérations CRUD sur la table des utilisateurs (c'est-à-dire supprimer un utilisateur). Lorsque l'utilisateur est supprimé, cependant, la table ne se met pas à jour pour refléter cette modification. La méthode que je me sers actuellement (essayer) de frais de la table est en appelant une fonction de rafraîchissement dans le rappel de succès de l'opération de suppression:

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

En dépit d'appeler cette fois l'opération terminée, l'observable combineLatest ne le fait pas se "déclenché" à nouveau et les données de la liste restent obsolètes. Existe-t-il un meilleur moyen d'actualiser les données générées par combineLatest avec les requêtes http?

Répondre

1

Le problème principal est que dans le cas d'une mise à jour de liste d'utilisateurs, vos utilisateurs $ observables n'émettent aucune nouvelle valeur. Vous devez le faire faire.

Ce squelette est d'une idée comment le résoudre:

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

Cela a beaucoup de sens, merci pour la suggestion. Je pense qu'il me manque quelque chose avec mon implémentation, car maintenant je ne reçois aucune donnée de table (même quand je change de filtre). J'ai changé refreshUserList() {updateUsersTrigger.next(); } et appelez ceci dans ngOnInit() mais toujours pas de chance. – natmegs

+0

@natmegs, essayez quelque chose comme ceci: 'updateUsersTrigger.startWith (null) .switchMap (() => ... appelle le service ...)' au lieu d'émettre quelque chose dans ngOnInit() - je ne m'attendrais pas à ce qu'il fonctionne En fait, je pense qu'il se déclenche trop tôt. –

0

Je ne suis pas en mesure de commenter, donc je vais écrire ici et me corriger si je me trompe ou si cela est hors de la question. Si vous utilisez .splice() lors d'une suppression réussie pour mettre à jour le DOM au lieu d'envoyer une autre requête http, cela ne serait-il pas plus facile et moins contraignant pour le client?

+0

De toute façon, OP a besoin de quelque chose d'observable pour émettre un nouveau tableau, qu'il s'agisse d'une requête http ou d'une opération splice() qui aboutissent à Observable.map() ou à autre chose. –