ngrx ofType,@ ngrx / effects

时间:2017-08-03 16:53:24

标签: angular typescript ngrx ngrx-effects

我试着理解ngrx中引人注目的效果是如何起作用的, 如果我在我的app模块中声明:

....

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

....

我写效果文件肯定:

@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'};
});

我试着理解,现在在运行时我发出一个动作 订阅this.action $并且每次执行ofType以匹配类型? 或ofType一旦执行!?

如果它调用了一次,当我发出动作时效果如何知道每次有效的订阅/执行?

谢谢大家!

4 个答案:

答案 0 :(得分:11)

简而言之,当.ofType()被调用时,它会订阅源操作流并将匹配操作推送到结果流。所以它确实被称为一次。

如果我们查看source code,我们会看到引擎ofType使用filter库的rxjs运算符,这意味着this.action$.ofType(CREATE_TASK)可以被扩展到

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

filter docs可以找到rxjs工作原理的说明:

  

与众所周知的Array.prototype.filter方法类似,此运算符从源Observable中获取值,将它们传递给predicate函数,并仅发出那些产生true的值。

值得注意的是,每个效果都会将一个可观察的(this.action$)作为输入,并返回一个新的observable,只有在初始化效果时才会预订一次。返回的observable定义了输入observable的动作如何被转换的方式,但它不会影响源observable本身。

在您的示例中,ofType()方法返回一个新的observable,它“侦听”this.action$ observable并仅发出满足条件action.type === CREATE_TASK的操作。然后转到map运算符,它还返回一个新的observable,它“监听”ofType()调用返回的observable,并根据您传递的投影函数将它接收的每个动作转换为新值。但是所有这些可观察对象在初始化时只创建一次,当你发送动作时,它们只是“流过”可观察对象,被过滤和转换。

您可能还想更熟悉rxjs。我建议你查看AndréStaltz的"You will learn RxJS"讲话,它应该让你直观了解可观察的内容以及它们是如何工作的。

答案 1 :(得分:2)

重点是在ngrx / effects内的Actions类中不会导出ofType 因此您可以像下面这样使用它: 1-从ngrx / effects导入

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)))
      );
    })
  );
}

答案 2 :(得分:1)

this.actions $ 在化繁为简的情况下,每次分派动作时都会调用.ofType(CREATE_TASK)。 喜欢 Redcucer

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

如果您对类型为'CREATE_TASK'的效果有任何影响,则首先执行reducer,然后生效。 在订阅模式中,无论您有什么订阅,这都会被回调,并将根据条件存储在数组中。当您基于条件调度动作时,所有函数都会调用满足条件的人。

答案 3 :(得分:0)

您还可以从每个效果分派一系列动作。

Read this article from medium