【问题标题】:Angular 2 Ngrx Store, Effects and "Ephemeral States"Angular 2 Ngrx 存储、效果和“临时状态”
【发布时间】:2017-02-16 09:02:08
【问题描述】:

在表单组件的上下文中工作:

我试图向用户显示表单的状态“待定、成功、错误、原始”。我不想将这些状态放在商店中,因为它们是“临时状态”。

我有一个效果:

@Effect()
  addTagToVideoEffect_ = this.appState_
    .ofType(TagActions.ADD_TAG_TO_VIDEO)
    .map<AddTagToVideo>(action => action.payload)
    .switchMap((addTag: AddTagToVideo) => this.dtsiVideosService.addTagToVideo(addTag)
      .map((addTag: AddTagToVideo) => TagReducers.addTagToVideoComplete(addTag))
      .catch((err) =>Observable.throw(err))
    );

在我的表单组件中,我发送TagActions.ADD_TAG_TO_VIDEO 并订阅它:

onTag(tag: TagEntity) {

    this.subscription = this.tagActions.addTagToVideoEffect_.subscribe(
      this.onAddTagSuccess,
      this.onAddTagError
    );

    this.tagActions.addTagToVideo({videoId: this.videoId, tag: tag});
}

.tagActions.addTagToVideoEffect_.subscribe 导致我的效果被调用了两次。我们如何才能在视图中获得效果的结果,而无需为所有这些短暂状态经过商店?并且没有两次调用的效果......

【问题讨论】:

    标签: angular ngrx


    【解决方案1】:

    你得到两次效果调用的原因是因为它只是一个 Observable。你需要把它变成一个Publisher。

    @Effect()
      addTagToVideoEffect_ = this.appState_
        .ofType(TagActions.ADD_TAG_TO_VIDEO)
        .map<AddTagToVideo>(action => action.payload)
        .switchMap((addTag: AddTagToVideo) => this.dtsiVideosService.addTagToVideo(addTag)
          .map((addTag: AddTagToVideo) => TagReducers.addTagToVideoComplete(addTag))
          .catch((err) => Observable.throw(err))))
        .share();
    

    然后你可以在你的视图中使用它:

    tagFormState_: BehaviorSubject<FormState> = new BehaviorSubject<FormState>({});
    
    
      onTag(tag: TagEntity) {
    
      Observable.from(this.tagActions2.addTagToVideoEffect_)
      .first()
      .toPromise()
      .then(this.onAddTagSuccess, this.onAddTagError)
    
        this.tagFormState_.next({pending: true});
        this.tagActions.addTagToVideo({videoId: this.videoId, tag: tag});
      }
    
    
      onAddTagSuccess = (payload) => {
        this.tagFormState_.next({success: 'Success !'});
        this.resetTagFormState();
      }
    
      onAddTagError = (err) => {
        this.tagFormState_.next({error: err.message});
        this.resetTagFormState();
      }
    
      resetTagFormState() {
        setTimeout(_=> {
          this.tagFormState_.next({});
        }, 1000);
      }
    

    帮助我解决这个问题的相关资源:

    【讨论】:

    • 那么,您是说所有效果都需要.publish().refCount()?规则是什么?
    • 这里是关于这个主题的更深入的对话:github.com/ngrx/effects/issues/59
    • 当视图需要显示效果的短暂结果并且我不希望或不需要商店中的那些状态时,我会使用它。此外,它还削减了许多样板 Action Effects Reducers :)
    • 这个问题在其他采用 Redux 模式的框架中也遇到过goshakkk.name/should-i-put-form-state-into-redux
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 2017-12-04
    • 2019-05-01
    • 1970-01-01
    • 2022-07-17
    • 2016-12-30
    • 1970-01-01
    相关资源
    最近更新 更多