Эффекты Ngrx: вывод не добавляется в поток действий - PullRequest
0 голосов
/ 26 сентября 2018

Проблема может быть повторена в этом стеке бликов .

Пример прост: пользователь выбирает расу и специальность.

Я хочу, чтобы при выборе расы специальность сбрасывалась (ред.).

Для этого я создал эффект:

@Effect()
raceChange = this.actions
  .pipe(
    ofType(SET_RACE),
    mapTo(new SetSpecialtyAction(''))
  );

Нодействие не добавляется в поток.Может ли кто-нибудь объяснить мне, почему?(Я новичок в @ngrx, поэтому, пожалуйста, будьте внимательны!)

PS: я знаю, что могу использовать решение из моего предыдущего вопроса , но я пытаюсь изучить основы ngrx,

код для компонента 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.raceStore.select('race');
  currentSpecialty = this.specStore.select('specialty');

  constructor(
    public raceStore: Store<RaceState>,
    public specStore: Store<SpecialtyState>,
    ) {
      this.currentRace.subscribe(x => console.log('race : ', x));
      this.currentSpecialty.subscribe(x => console.log('spec : ', x))
    }

  dispatchRace(race) {
    this.raceStore.dispatch(new SetRaceAction(race));
  }

  dispatchSpecialty(spec) {
    this.specStore.dispatch(new SetSpecialtyAction(spec));
  }
}


export const SET_RACE = '[RACE] Set';
export 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 RaceState {
  readonly race: string;
}

export interface SpecialtyState {
  readonly specialty: string;
}

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Эффект не нужен, вы можете слушать гонку внутри специального редуктора:

export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction | SetRaceAction): string {
  switch(action.type) {
    case SET_RACE:
      return '';
    default:
     return action.specialty || state;
  }
}
0 голосов
/ 26 сентября 2018

mapTo отображает излучение в строку, с помощью map сопоставляется действие, которое будет отправлено.

Чтобы ваш пример работал, я изменил две вещи:

1- замените mapTo на map в результате:

@Effect()
raceChange = this.actions
   .pipe(
     ofType(SET_RACE),
     map(() => new SetSpecialtyAction(''))
);

2- Измените редуктор, игнорирующий пустые значения:

export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction): string {
  return action.specialty;
}

const value = '' || 'Not Empty';
console.log(value);

Вот рабочий форк.

Вы также можете сопоставить несколько действий, используя switchMap и возвращая массив для действий:

@Effect()
raceChange = this.actions
   .pipe(
     ofType(SET_RACE),
     switchMap(() => [new SetSpecialtyAction(''), ...])
);
...