3

所以我通常有一个方法可以在点击时调度一个动作:

create() {
  this.store.dispatch(new Create(this.form.value)); 
}

此代码触发以下场景并根据请求是否失败分派 CreateSuccess 或 CreateFailed

@Action(Create)
create({ dispatch }: StateContext<StateInterface>, { entity}: Create) {
  return this.http.post('mybackend', entity).pipe(
    tap<EntityType>(resp => dispatch(new CreateSuccess(resp))),
    catchError(error => dispatch(new CreateFailed(error)))
  ); 
}

现在在我调用的组件内部,create()我正在监听这两个动作。

this.actions$.pipe(
  ofActionSuccessful(CreateSuccess, UpdateSuccess),
  takeUntil(componentDestroyed(this)) // <--
).subscribe(action => doStuff());

这一切都完美无缺,唯一困扰我的是每次我使用它时,我都必须添加 takeUntil() 部分,以便在组件被销毁时取消订阅。

我知道这对每个人来说可能都不是一个真正的问题,但我想知道是否有更清洁的方法来做到这一点。

我已经考虑过可以处理此问题的自定义 RxJS 运算符,但也许还有其他选项,或者(我还没有找到任何东西),NGXS 是否有办法自行取消订阅?

4

2 回答 2

3

在 NGXS 中,dispatch 方法返回一个 observable,一旦操作处理完成(不需要取消订阅),该 observable 就会完成。因此,在您的示例中Create,当操作的处理程序完成时,您的操作将完成。如果处理程序返回一个可观察对象(就像您所做的那样),那么完成将链接到该可观察对象的完成。如果你使用 amap而不是 atap来调度CreateSuccess动作,那么原始的 observable 将等待那个 'child' observable 首先完成。我会像这样构造处理程序,以使Create操作仅在CreateSuccess完成后完成:

@Action(Create)
create({ dispatch }: StateContext<StateInterface>, { entity}: Create) {
  return this.http.post('mybackend', entity).pipe(
    map<EntityType>(resp => dispatch(new CreateSuccess(resp))),
    catchError(error => dispatch(new CreateFailed(error)))
  ); 
}

然后在你的组件中你可以这样做:

create() {
  this.store.dispatch(new Create(this.form.value))
    .subscribe(action => doStuff()); 
}

当分派动作的处理(和“子”动作处理)完成时,observable 将完成。无需退订。

于 2018-10-31T19:05:48.550 回答
2

NGXS 不提供任何基于 Angular 组件生命周期的特殊功能来取消订阅。

通常,在组件被销毁时取消订阅是有意义的。但是,在某些情况下,您希望更具体地控制何时订阅/取消订阅。

因此,您必须在每个 Angular 组件的适当生命周期函数中对其进行管理。

于 2018-10-30T05:11:55.953 回答