web-dev-qa-db-fra.com

ngrx ofType, @ ngrx/effects

j'essaie de comprendre comment les effets de typeof fonctionnent sous le capot de ngrx, si je déclare dans mon module d'application: 

....

@NgModule({
    imports: [
        EffectsModule.forRoot([TodosEffectsService])
],

....

et j'écris le fichier d'effet bien sûr:

@Effect() createTodos$ = this.actions$
.ofType(CREATE_TASK)
    .map(() => {
        console.log('called');
            return { type: 'OTHER'};
});

@Effect() addTodos$ = this.actions$
.ofType(CREATE_TASK)
    .map(() => {
        console.log('called');
            return { type: 'OTHER'};
});

j'essaie de comprendre que maintenant, au moment de l'exécution, j'envoie une action this.action $ est souscrit et chaque fois, exécutez ofType pour correspondre au type? ou ofType une fois execute !?

s’il appelle une fois, quand j’envoie une action, comment les effets savent-ils à chaque fois qu’un effet doit être souscrit/exécuté?

merci à tous!

6
Alin

En un mot, lorsque .ofType() est appelé, il s’abonne au flux d’actions source et pousse les actions correspondantes dans le flux résultant. Donc, il est en effet appelé une fois.

Si nous regardons le code source , nous verrons que, sous le capot, ofType utilise l'opérateur filter de la bibliothèque rxjs, ce qui signifie que this.action$.ofType(CREATE_TASK) peut être étendu à

this.action$.filter(action => action.type === CREATE_TASK)

Vous trouverez une description du fonctionnement de filter à partir de rxjsdocs :

Semblable à la méthode bien connue Array.prototype.filter, cet opérateur prend des valeurs dans l'observable source, les transmet à travers une fonction predicate et n'émet que les valeurs qui ont généré true.

Il est à noter que chacun de vos effets prend un observable (this.action$) en entrée et renvoie un nouvel observable qui n'est souscrit qu'une seule fois, lorsque les effets sont initialisés. L'observable renvoyé définit la façon dont les actions de l'observable d'entrée est transformée, mais n'affecte pas l'observable source.

Dans votre exemple, la méthode ofType() renvoie une nouvelle observable qui "écoute" la variable this.action$ observable et n'émet que les actions répondant à la condition action.type === CREATE_TASK. Vient ensuite l'opérateur map. Il renvoie également une nouvelle observable qui "écoute" l'observable renvoyé par l'appel ofType() et transforme chaque action reçue en une nouvelle valeur en fonction d'une fonction de projection que vous transmettez. Mais tous ces observables ne sont créés qu’une fois, lors de l’initialisation, et lorsque vous envoyez des actions, elles «circulent» dans les observables, sont filtrées et transformées.

Vous voudrez peut-être aussi vous familiariser davantage avec rxjs. Je vous recommanderais de vérifier "Vous apprendrez RxJS" le discours d’André Staltz, cela devrait vous donner une intuition de ce que sont les observables et de leur fonctionnement.

11
Sergey Karavaev

Le fait est que le type n’est pas exporté dans la classe Actions de ngrx/effects . Vous pouvez donc l’utiliser comme suit:

import { Injectable } from "@angular/core";

import { Effect, Actions, ofType } from "@ngrx/effects";
import * as omid from "@ngrx/effects";
import { of } from "rxjs";
import { map, switchMap, catchError } from "rxjs/operators";
@Injectable()
export class PizzasEffects {
  constructor(
    private actions$: Actions,
    private pizzaService: frtomServices.PizzasService
  ) {}

  @Effect()
  LoadPizzas$ = this.actions$.pipe(
    ofType(pizzaActions.LOAD_PIZZAS),
    switchMap(() => {
      return this.pizzaService.getPizzas().pipe(
        map(pizzas => new pizzaActions.LoadPizzasSuccess(pizzas)),
        catchError(error => of(new pizzaActions.LoadPizzasFail(error)))
      );
    })
  );
}
1

this.actions $ . ofType (CREATE_TASK) appelle à chaque fois que votre action est envoyée, après que votre cas réducteur soit exécuté. comme Redcucer

switch(action) {
case youractionsname.CREATE_TASK : {
// pure function logic here
   }
}

Le premier réducteur sera exécuté et ensuite, il vérifiera l'effet si vous avez un effet quelconque sur le type 'CREATE_TASK'. Dans le modèle d'abonnement, tout ce que vous avez souscrit sera une fonction de rappel et sera stocké dans un tableau sous le capot en fonction de la condition. Lorsque vous envoyez une action à la condition que toutes les fonctions appellent les personnes qui remplissent la condition. 

1
viveksharma