Angular 2 Ngrx Store,Effects和" Ephemeral States"

时间:2016-10-06 00:30:46

标签: angular ngrx

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

我试图向用户显示表单的状态"挂起,成功,错误,原始"。我不想在商店中拥有这些状态,因为他们是短暂的状态"。

我有一个效果:

@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导致我的效果被调用两次。如何在没有经过商店的所有短暂状态的情况下获得视图中效果的结果?没有两次效果......

1 个答案:

答案 0 :(得分:3)

两次获得效果调用的原因是因为它只是一个Observable。您需要将其转换为发布者。

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

有关这个主题的资源帮助我解决了这个问题: