Ngrx 效果:输出未添加到操作流
Ngrx effects : output not getting added to the actions stream
问题可以在 this stackblitz 中重现。
示例很简单:用户选择种族和专业。
我希望在选择种族时重置专精(编辑?)。
为此,我创建了一个效果:
@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;
}
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(''), ...])
);
不用效果器,可以听专业减速器里面的race动作:
export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction | SetRaceAction): string {
switch(action.type) {
case SET_RACE:
return '';
default:
return action.specialty || state;
}
}
问题可以在 this stackblitz 中重现。
示例很简单:用户选择种族和专业。
我希望在选择种族时重置专精(编辑?)。
为此,我创建了一个效果:
@Effect()
raceChange = this.actions
.pipe(
ofType(SET_RACE),
mapTo(new SetSpecialtyAction(''))
);
但是动作没有被添加到流中。有人可以向我解释为什么吗? (我是@ngrx 的新手,所以请彻底了解!)
PS :我知道我可以使用
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;
}
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(''), ...])
);
不用效果器,可以听专业减速器里面的race动作:
export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction | SetRaceAction): string {
switch(action.type) {
case SET_RACE:
return '';
default:
return action.specialty || state;
}
}