【问题标题】:how to select form ngrx store within an Effect using a slector with parameters如何使用带有参数的选择器在效果中选择表单ngrx存储
【发布时间】:2018-11-28 12:41:12
【问题描述】:

我需要构建一个 Effect 并且我需要一个来自 store 的值,问题是选择器是一个带参数的选择器。

按照示例代码:

        @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]*/)

【问题讨论】:

    标签: angular rxjs ngrx ngrx-effects


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您可以创建特定的选择器并在调用withLatestFrom 时使用它们。

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

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

      选择参考

      选择工作

      是 NGRX 选择器,代码如下所示:

      //create slice
      const requestState= createFeatureSelector<IRequestState>(feature);
      
      //get exactly what you need from the state, not extra stuff
      export const selectReference= createSelector(requestState, (state) => state?.reference);
      
      export const selectWork= createSelector(requestState, (state) => state.Work);
      

      保持干净,不要重复选择代码。我怀疑你需要带参数的选择器。尝试在选择器中获取列表,并通过另一个选择器获取参数。在 switchMap 函数中执行逻辑(或任何最适合您的方法,mergeMap 或 concatMap)

      【讨论】:

        【解决方案3】:

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 2019-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-12
            • 2022-04-21
            • 2019-09-30
            • 2023-02-04
            相关资源
            最近更新 更多