【问题标题】:Ngrx effects : output not getting added to the actions streamNgrx 效果:输出未添加到操作流中
【发布时间】:2018-09-26 11:24:05
【问题描述】:

问题可以在this stackblitz中重新解决。

示例很简单:用户选择种族和专业。

我希望在选择种族时重置专长(ed ?)。

为此,我创建了一个效果:

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

但该操作并未添加到流中。有人可以解释一下为什么吗? (我是 @ngrx 的新手,所以请彻底!)

PS:我知道我可以使用the solution from my previous question,但我正在尝试学习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;
}

【问题讨论】:

    标签: angular typescript ngrx ngrx-effects


    【解决方案1】:

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

    Here is a working fork.

    您还可以使用 switchMap 映射到多个操作并返回一个数组 fo 操作:

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

    【讨论】:

    • 该死的,我完全忘记了我忽略了空值!仅此一项就解决了我的问题。我也在考虑您对mapToswitchMap 的评论,谢谢!如果您知道如何快速提问:鉴于我有两个动作,我怎么能在我的效果中发出 SetRaceAction 而不会触发无限循环?我必须为此创建一个新状态吗?
    • 从技术上讲,您可以在效果RxJs 管道中使用过滤器来防止无限循环。但我会避免可能相互触发的效果。
    【解决方案2】:

    不需要效果,可以在专业reducer里面听race action:

    export function specialtyReducer(state: string = undefined, action: SetSpecialtyAction | SetRaceAction): string {
      switch(action.type) {
        case SET_RACE:
          return '';
        default:
         return action.specialty || state;
      }
    }
    

    【讨论】:

    • 这正是我所说的我已经在使用,我不想使用,因为我正在学习效果。
    • 我想在这里为我的回答辩护一下,因为你没有这么说,而且你没有使用我在这里写的解决方案。如果您想学习效果,您还应该知道何时使用效果以及何时不应该使用效果。这种情况并没有真正“做”副作用,只是改变状态,因此适合使用减速器。此外,当您引入更多操作时,接受的答案可能会在稍后引入麻烦,因为当操作没有提供 specialty 时,reducer 将始终清除状态。
    • 这是minimal reproducible example,并非真实案例。我正在尝试了解效果如何工作以及它们的作用。感谢接受的答案,我现在这样做。我含蓄地说我正在使用这个解决方案,它在我的问题中链接,你显然根本没有读过。您的回答很好,不要误会我的意思,我没有任何反对意见:我的问题是您完全忽略了问题的上下文,基本上创建了一个重复项。这个问题是关于效果不起作用(因为我做了一些愚蠢的事情),而不是关于在那里使用的最佳解决方案是什么。
    • :thumbsup: 我一定是把你的问题理解错了。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 2019-11-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多