当另一个动作成功时调度一个动作

问题描述

我对angular和redux世界是陌生的。我想我有一个常见的问题,但是我找不到正确的答案,或者我只需要一个有用的提示。我在应用程序中使用ngrx,我想更新用户的一些基本数据。然后,我想重新加载用户的数据。

简而言之 (1)更新用户数据 (2)加载用户数据 (3)在前端可视化

如果我先派遣更新然后加载数据,则它并不总是有效。我了解到调度程序是异步运行的,因此不能说哪个先完成。

我的主意。我将必须(1)用Promise更新用户数据,然后(2)加载并显示用户数据。还是我错了?

感谢您的帮助


这是我的代码

currenUser.effects.ts

[...]

@Injectable()
export class CurrentUserEffects {

  constructor(
    private actions$: Actions,private currentUserService: CurrentUserService
    ) {}

    @Effect()
    loadCurrentUser$ = this.actions$.pipe(
      ofType(ActionTypes.LoadCurrentUser),mergeMap((action: LoadCurrentUserAction) =>
        this.currentUserService
          .getCurrentUserNew()
          .pipe(
              map(
                (currentUser: CurrentUserNew) => new LoadCurrentUserActionFinished(currentUser)
              )
          )
      )
    );

    @Effect()
    updateCurrentUser$ = this.actions$.pipe(
      ofType(ActionTypes.UpdateCurrentUser),switchMap((action: UpdateCurrentUserAction) =>

        // update
        this.currentUserService
          .updateCurrentUser(action.oldCurrentuser,action.newCurrentUser)
          .then(
            response => {
                return new UpdateCurrentUserActionFinished(response);
            }
          )

        // here relaod data?

      )
    );
}

currentUser.actions.ts

import { CurrentUserNew } from './../../models/currentUserNew';
import { Action } from '@ngrx/store';

export enum ActionTypes {
  LoadCurrentUser = '[CurrentUser] Load current user',LoadCurrentUserFinished = '[CurrentUser] Load current user finished',UpdateCurrentUser = '[CurrentUser] Update current user',UpdateCurrentUserFinished = '[CurrentUser] Update current user finished',}

export class LoadCurrentUserAction implements Action {
  readonly type = ActionTypes.LoadCurrentUser;
}

export class LoadCurrentUserActionFinished implements Action {
  readonly type = ActionTypes.LoadCurrentUserFinished;
  constructor(public payload: CurrentUserNew) {}
}

export class UpdateCurrentUserAction implements Action {
  readonly type = ActionTypes.UpdateCurrentUser;
  constructor(
    public oldCurrentuser: CurrentUserNew,public newCurrentUser: CurrentUserNew
     ) {}
}

export class UpdateCurrentUserActionFinished implements Action {
  readonly type = ActionTypes.UpdateCurrentUserFinished;
  constructor(public payload: boolean) {}
}

export type CurrentUserActions =
  | LoadCurrentUserAction
  | LoadCurrentUserActionFinished
  | UpdateCurrentUserAction
  | UpdateCurrentUserActionFinished;

currentUser.reducer.ts

import { CurrentUserNew } from './../../models/currentUserNew';
import { CurrentUserActions,ActionTypes } from './currentUser.actions';

export interface ReducerCurrentUserState{
  currentUser: CurrentUserNew;
  isUpdated: boolean;
}

export const initialState: ReducerCurrentUserState = {
  currentUser: null,isUpdated: false
};

export function currentUserReducer(
  state = initialState,action: CurrentUserActions
): ReducerCurrentUserState {


  switch (action.type) {
    case ActionTypes.LoadCurrentUser: {
      return {
        ...state,};
    }

    case ActionTypes.LoadCurrentUserFinished: {
      return {
        ...state,currentUser: action.payload,};
    }

    case ActionTypes.UpdateCurrentUser: {
      return {
        ...state,};
    }

    case ActionTypes.UpdateCurrentUserFinished: {
      return {
        ...state,isUpdated: action.payload,};
    }

    default:
      return state;
  }

}

currentUser.selectors.ts

import { ReducerCurrentUserState,currentUserReducer } from './currentUser.reducer';
import { ActionReducerMap,createFeatureSelector,createSelector } from '@ngrx/store';

export const currentUserFeatureStateName = 'currentUserFeature';

export interface CurrentUserState {
  currentUser: ReducerCurrentUserState;
}

export const currentUserReducers: ActionReducerMap<CurrentUserState> = {
  currentUser: currentUserReducer,};

// extract the main property from the state object
export const getCurrentUserFeatureState = createFeatureSelector<CurrentUserState>(
  currentUserFeatureStateName
);

export const getCurrentUser = createSelector(
  getCurrentUserFeatureState,(state: CurrentUserState) => state.currentUser.currentUser
)

export const isCurrentUserUpdatedSuccessful = createSelector(
  getCurrentUserFeatureState,(state: CurrentUserState) => state.currentUser.isUpdated
)

解决方法

起初我试图在一个效果中调用两个动作

    @Effect()
    updateAndLoadCurrentUser$ = this.actions$.pipe(
        ofType(ActionTypes.UpdateAndLoadCurrentUser),switchMap((action: UpdateCurrentUserAction) =>
            of(
                new UpdateCurrentUserAction(action.oldCurrentuser,action.newCurrentUser),new LoadCurrentUserAction(),new UpdateAndLoadCurrentUserActionFinished()
            )
        )
    );

这里的问题是动作应使我得到异步答案。

我的解决方案:

实际上,我的解决方案是我叫一个动作。该操作向后端调用http请求,后端为我提供了正确的对象。

但是,我现在对如何触发两个动作很感兴趣。不幸的是,我还没有找到解决方案