使用 NGXS 订阅操作流的更简洁方式

Ein*_*rzt 7 redux angular ngxs

所以我通常有一种在点击时调度操作的方法:

create() {
  this.store.dispatch(new Create(this.form.value)); 
}
Run Code Online (Sandbox Code Playgroud)

此代码触发以下场景,并根据请求是否失败调度 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)))
  ); 
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

我考虑过一个自定义的 RxJS 运算符可以处理这个问题,但也许还有其他选项,或者(我还没有找到任何相关内容),NGXS 有没有办法自行取消订阅?

Mar*_*eld 5

在 NGXS 中,dispatch 方法返回一个可观察对象,一旦操作处理完成(无需取消订阅),该可观察对象就会完成。因此,在您的示例中,Create当操作的处理程序完成时,您的操作将完成。如果处理程序返回一个可观察值(就像您所做的那样),则完成会链接到该可观察值的完成。如果您使用 amap而不是 atap来分派操作CreateSuccess,那么原始可观察对象将等待该“子”可观察对象首先完成。我将像这样构造处理程序,以便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)))
  ); 
}
Run Code Online (Sandbox Code Playgroud)

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

create() {
  this.store.dispatch(new Create(this.form.value))
    .subscribe(action => doStuff()); 
}
Run Code Online (Sandbox Code Playgroud)

当分派操作的处理(和“子”操作处理)完成时,可观察对象将完成。无需取消订阅。