代码之家  ›  专栏  ›  技术社区  ›  Maryannah

NGRX:将一个事件从一个存储发送到另一个存储

  •  0
  • Maryannah  · 技术社区  · 6 年前

    我开始使用@ngrx,我面临一个问题,我似乎找不到答案。

    我用图解说明 this stackblitz :当玩家选择一场比赛时,该专长应设置回未定义。

    一开始我以为我可以使用减速器,但它不知道商店没有注射。

    我应该如何处理这个问题?
    (注意:这是一个可复制的示例,我知道我可以在函数中放置第二个分派。我想要的是自动完成)

    相关代码:

    import { Component } from '@angular/core';
    import { Store, Action, ActionReducerMap } from '@ngrx/store';
    
    @Component({
      selector: 'my-app',
      template: 
    `
    <select #race (change)="dispatchRace(race.value)" placeholder="Select a race">
      <option value="Elf">Elf</option>  
      <option value="Orc">Orc</option>  
      <option value="Dwarf">Dwarf</option>
    </select>
    
      <select #spec (change)="dispatchSpecialty(spec.value)" placeholder="Select a specialty">
      <option value="Warrior">Warrior</option>  
      <option value="Berzerkrer">Berzerkrer</option>  
      <option value="Healer">Healer</option>  
    </select>
    
    <p>
      Current race: {{ (currentRace | async) || 'None' }}
    </p>
    <p>
      Current Spec: {{ (currentSpecialty | async) || 'None' }}  
    </p>  
    `
    })
    export class AppComponent {
    
      currentRace = this.store.select('race');
      currentSpecialty = this.store.select('specialty');
    
      constructor(public store: Store<CharacterState>) { }
    
      dispatchRace(race) {
        this.store.dispatch(new SetRaceAction(race));
      }
    
      dispatchSpecialty(spec) {
        this.store.dispatch(new SetSpecialtyAction(spec));
      }
    }
    
    
    const SET_RACE = '[RACE] Set';
    const SET_SPECIALTY = '[CLASS] Set';
    
    export class SetRaceAction implements Action {
      readonly type = SET_RACE;
      constructor(public race: string) { }
    }
    
    export class SetSpecialtyAction implements Action {
      readonly type = SET_SPECIALTY;
      constructor(public specialty: string) { }
    }
    
    export function raceReducer(state: string = undefined, action: SetRaceAction): string {
      return action.race || state;
    }
    
    export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction): string {
      return action.specialty || state;
    }
    
    export interface CharacterState {
      readonly race: string;
      readonly specialty: string;
    }
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   ibenjelloun    6 年前

    如果添加 console.log raceReducer 您可以看到所有动作都由所有减速器处理:

    export function raceReducer(state: string = undefined, action: SetRaceAction): string {
      console.log(action);
      return action.race || state;
    }
    

    你只需要处理 SetRaceAction SetSpecialtyAction 不同的。

    Edit of the stackblitz.

        2
  •  1
  •   FussinHussin    6 年前

    所以如果我理解正确的话:你想调度一个触发另一个动作的动作?

    1. 最好使用NGRX效果。 . 您的效果文件将监听该操作,并在捕获该操作时同时发送。(请原谅,我有格式化问题)

    // make sure to import rxjs 6 correctly
    import { map, switchMap, tap } from 'rxjs/operators';
    
    @Effect()
    twoActionEvent = this.actions$
        .ofType(appActions.FIRST_ACTION)
        .pipe(
            switchMap((action$: appActions.firstAction) => {
                return //what ever you need in the first action
            }),
            map((firstActionPayload) => {
                return {
                   type: appActions.FIRST_ACTION_SUCCESS,
                    payload: firstActionPayload
                }
             }),
             tap(() => {
                 this.store.dispatch(new appActions.SecondAction(//payload))
             })
         );
    constructor(private actions$: Actions,
                private store: Store<AppState>) {}
    1. 另一种方法是通过订阅存储区中的属性来监听应用程序中的操作,当该属性为真时:调度第二个操作
        3
  •  0
  •   FussinHussin    6 年前

    我想再添加一个解决方案,这是我在自己的实现中使用存储区中的标志时所做的。

    只需在发送操作期间更改状态中的标志,例如:

    import * as AppActions from './app.actions'; import * as handler from './app.models';
    
    export function appReducer(
            state: handler.AppState = handler.initialAppState,
            action: AppActions.AppActions
        ) {
            switch(action.type) {
                case AppActions.SET_RACE_ACTION:
                    return {
                        ...state,
                        race: action.payload
                        // set your flag in state
                        myFlag: undefined
                     }
           }
    

    }