如何使用带有参数的slector在效果内选择form ngrx存储

时间:2018-11-28 12:41:12

标签: angular rxjs ngrx ngrx-effects

我需要构建一个效果,我需要从存储中获取一个值,问题是选择器是带有参数的选择器。

下面的示例代码:

        @Effect()
      ExampleEffect$ = this.actions$.pipe(
        ofType(
          ActionTypes.SOMETHING
        ),
        map((action: Somthing) => action.payload.myParameter),
// HERE I NEED THE PARAMETER TO PERFROM THE SELECTION
        withLatestFrom(this.store.pipe(select(selectorWithParamter(myParameter))),
        map((value) => /* do somthing with the array [myParameter, valueSelected from sotre]*/)

4 个答案:

答案 0 :(得分:2)

您可以在创建选择器时编写箭头函数来传递参数。

export const getAlbumById = (collectionId: number) => createSelector(getAlbumEntities, entities => entities[collectionId]);

更多示例

//效果

@Effect({ dispatch: true })
  upsertAlbum$ = this.actions$.pipe(
    ofType(AlbumActionTypes.UpsertAlbum),
    map((action: any) => action.payload),
    mergeMap(({ album }) =>
      this.store.pipe(
        select(selectAlbumIfExists(album.id)),
        first(),
        map(isAlbumHasName => [album, isAlbumHasName])
      )
    ),
    filter(([album, isAlbumHasName]) => !isAlbumHasName),
    map(([album]) => new LoadAlbum({ album }))
  );

//选择器

export const selectAlbumIfExists = (id: string) =>
  createSelector(
    selectAlbumsEntities,
    entities => !!(entities[id] && entities[id].name)
  );

答案 1 :(得分:2)

您可以创建特定的选择器,并在调用spring: datasource.url: <some url here> flyway: init-sqls: SET OWNER <owner of tables created via migration scripts> url: ${spring.datasource.url} 时使用它们。

withLatestFrom

如上所述,请尝试使用选择器。就我而言,

selectReference

selectWork

是NGRX选择器,代码如下:

 approve$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(myactions.approve),
      withLatestFrom(this.store.select(selectReference), this.store.select(selectWork)),
      switchMap(([_, reference, work]) => this.service.approve(reference, work)),
      map(() => actions.approveSuccess())
    );
  });

请保持清洁,不要重复选择代码。我怀疑您是否需要带参数的选择器。尝试在选择器中获取列表,并通过另一个选择器获取参数。在switchMap函数中执行逻辑(或者最适合您的是mergeMap或concatMap)

答案 2 :(得分:0)

答案 3 :(得分:0)

andreisrob 的建议很好。下面提供了一个完整的工作示例。这显示了效果如何使用来自需要参数的选择器的值。

updateQuestionnaireTranslationValue$ = createEffect(() => this.actions$.pipe(
    ofType(QuestionnaireTranslationsUpdateValueAction),
    concatMap((action) => {
        this.store.dispatch(GlobalLoadingStartedAction({ message: "Updating translation value ..."}));

        const props = { formId: action.payload.formId, langId: action.payload.translationLanguageId};
        const update$ = this.store.pipe(
            select(selectQuestionnaireTranslationResourceCount, props),
            first(),
            concatMap(translatableCount => {
                const updateRes$ = this.questionnaireService.updateTranslation(action.payload, translatableCount).pipe(
                    tap(() => this.store.dispatch(GlobalLoadingEndedAction())),
                    catchError(err => {
                        this.store.dispatch(GlobalLoadingEndedAction());
                        this.logger.logErrorMessage("Error updating translation value: " + err);
                        this.snackBar.openError("Failed to update translation value");

                        this.store.dispatch(QuestionnaireTranslationsUpdateValueCancelledAction());
                        return of(null);
                    })
                );
                return updateRes$;
            })
        );
        return update$.pipe(map(count => ({ value: action.payload, totalCount: count } )));
    }),
    map((payload: ({ value: QuestionnaireTemplateTranslationUpdateValue, totalCount: number })) => {
        return QuestionnaireTranslationsUpdateValueDoneAction({ payload });
    }))
);