ngrx效果创建一个无限循环

时间:2020-01-27 08:26:55

标签: angular ngrx

我是ngrx的新手,并且是该项目团队的新手。当我单击用户名提供其真实图表时,我的应用程序会挂起,我认为这是因为ngrx效果创建了一个无限循环。这是效果代码:

      @Effect()
myObjectivesRequested$ = this.actions$
    .pipe(
        ofType<MyObjectivesRequested>(ObjectivesActionTypes.MyObjectivesRequested),
        mergeMap(({payload}) => {
            this.store.dispatch(this.showActionLoadingDistpatcher);
            return this.store.pipe(select(selectMyObjectivesIdsByCompanyId(payload.companyId))).pipe(
                take(1),
                mergeMap(myObjectives => {
                    if (myObjectives) {
                        return of(myObjectives);
                    } else {
                        return this.ObjectivesService.getMyObjectives(payload.companyId).pipe(
                            take(1),
                            map(res => {
                                return this.store.dispatch(new MyObjectivesLoaded({objectives: res, companyId: payload.companyId}));
                            })
                        );
                    }
                }));
        }),
        map(() => {
            return this.hideActionLoadingDistpatcher;
        }),
    );

1 个答案:

答案 0 :(得分:0)

对我来说,您使用take(1)很奇怪。 take(1)接收第一个发射并关闭可观察的流(使其死掉)。我看到您正在查看要查找的内容是否在商店中是否存在,然后再进行API调用,从而使商店成为缓存。

我会做的:

@Effect()
myObjectivesRequested$ = this.actions$.pipe(
  ofType<MyObjectivesRequested>(ObjectiveActionTypes.MyObjectivesRequested),
  switchMap(({ payload }) => {
    return this.store.pipe(
             select(selectMyObjectivesIdsByCompanyId(payload.companyId)),
             switchMap(myObjectives => {
               if (myObjectives) {
                 return of(myObjectives);
               } else {
                 return this.ObjectivesService.getMyObjectives(payload.companyId);
               }
            }),
            map(objectives => new MyObjectivesLoaded({objectives, companyId: payload.companyId}))
           ),
            // catch the error, return the action (this is optional)
            catchError(error => Observable.of(new MyObjectivesError(error))
  })
)

一些注意事项:

1。)select(selectMyObjectivesIdsByCompanyId(payload.companyId))应该是 选择器文件。

2。)我看到您使用商店时的调度动作。在减速器中,收听MyObjectivesRequested并打开loading。收听MyObjectivesLoaded,然后填充数据/目标切片,然后关闭loading。收听MyObjectivesError,然后关闭loading并将error转到错误所在。 然后,您还应该像针对selectMyObjectivesIdsByCompanyIdloading的{​​{1}}(这是数据/目标切片)那样使用选择器,并在组件中使用这些选择器来查看州。

error => https://github.com/DeborahK/Angular-NgRx-GettingStarted相关的良好存储库,其中Demo5是最高级的(内置的所有概念)。