3

我在我的应用程序中使用 ngrx/data 并试图弄清楚如何使用error$流来显示组件中的错误。基本上,我使用带有表单的模态弹出窗口来创建实体,并且我正在使用error$流来显示保存它时发生的任何错误。我遇到的问题是,如果发生错误并显示并在下次打开时关闭弹出窗口,则会显示上一个错误。这是error$选择器的代码

    this.entityActionErrors$ = actions.pipe(
      filter(
        (ea: EntityAction) =>
          ea.payload &&
          ea.payload.entityOp &&
          ea.payload.entityOp.endsWith(OP_ERROR)
      ),
      shareReplay(1)
    );

问题出在shareReplay(1). 我试图弄清楚如何在重新打开模式并再次订阅 error$ 流时忽略或过滤掉先前的错误。

rxjs 中有没有办法忽略或过滤掉来自 sharedReplay 主题的先前发射?

4

2 回答 2

4

我想出的解决方案是为错误消息使用单独的主题。我在为实体创建的服务类中执行了此操作。

export class VolunteersService extends EntityCollectionServiceBase<Volunteer> {
  constructor(factory: EntityCollectionServiceElementsFactory) {
    super('Volunteer', factory);

    this.errors$
      .pipe(
        filter(
          (ea: EntityAction) =>
            ea.payload.entityName === 'Volunteer' &&
            ea.payload.entityOp === EntityOp.SAVE_ADD_ONE_ERROR
        )
      )
      .subscribe(() => this._addErrorSubject.next('We couldn\'t save your changes at the moment. Please try again later.'));
  }

  private _addErrorSubject = new Subject<string>();

  get addError$(): Observable<string> {
    return this._addErrorSubject;
  }
}

我试图解决的问题是本地组件状态的问题,所以虽然这确实有效,但我决定采用不同的解决方案。在 ngrx/data 中,EntityCollectionServiceBase类中的所有命令方法都返回一个 Observable,该 Observable 在存储更新后发出。因此,在组件中,我订阅了命令方法,例如:

  save() {
    this._pending = true;
    this.volunteersService.add(volunteer).subscribe(
      () => {
        this._pending = false;
      },
      error => {
        this._pending = false;
        this._error = error.message;
      }
    );
  }

此解决方案完美运行,并将此状态保留在它所属的组件中和商店之外。

于 2019-12-13T06:25:35.097 回答
0

跳过存储值很简单:
errors$.pipe(skipUntil(timer(0));.
它之所以有效,是因为存储值是同步提供的。
您还可以使用 asyncScheduler。

于 2020-09-30T10:38:53.110 回答