【问题标题】:Angular return result of Subscription as Observable订阅的角度返回结果为 Observable
【发布时间】:2021-09-02 22:43:04
【问题描述】:

我有一个组件,在单击按钮时,它会从 StorageManagerService 调用 save() 方法:

// component.ts
onSaveClick(): void {
  this.storageManager
    .save(<objectToSave>)
    .pipe(take(1))
    .subscribe({
      next: (success: boolean) => {
        if (success) {
          // do stuff
        } else {
          // do other stuff
        }
      },
    });
}

该 storageManager 是另一个处理条件逻辑的服务的适配器。所以StorageManagerService.save() 如下所示:

// StorageManagerService
save(<objectToSave>): Observable<boolean> {
  if (<someCondition>) {
    this.modalService
      .openDialogWithComponent(
        SaveSystemContainerComponent,
        { data: { <someData> } },
        this.matDialog
      )
      .afterClosed()
      .pipe(take(1))
      .subscribe({
        next: (success: boolean) => {
          if (success) {
            // special handling

            return this.localStorageService.save(<objectToSave>);
          }

          return of(false);
        },
      });
  }
  else {
    return this.localStorageService.save(<objectToSave>);
  }
}

虽然LocalStorageManagerService 有存储数据的具体实现:

// LocalStorageManagerService
save(<objectToSave>): Observable<boolean> {
  if (this.storageAvailable()) {
    localStorage.setItem(<objectToSave>.id, JSON.stringify(<objectToSave>));
    return of(true);
  }

  console.error('local storage not available or disabled');
  return of(false);
}

LocalStorageService 继承自所有存储服务都必须实现的抽象类。 这个想法是,以后从localStorage迁移到实际数据库时,我只需要更改StorageManagerService中的变量,不必修改应用程序中的20多个地方。

我遇到的问题是,在某些情况下,用户必须先输入其他数据才能存储它。该输入通过出现的模式发生。 现在 TypeScript 告诉我 StorageManagerService 中的 if-case 没有返回任何内容(这是正确的)。

如何将StorageManagerService 中的subscribe.next() 的结果返回给调用函数?我想我缺少一个 rxjs 运算符。

【问题讨论】:

    标签: angular rxjs observable subscription


    【解决方案1】:

    如果有人订阅保存,您可以将方法重构为:

    save(objectToSave): Observable<boolean> {
      if (someCondition) {
        return this.modalService
          .openDialogWithComponent(
            SaveSystemContainerComponent,
            { data: { someData } },
            this.matDialog
          )
          .afterClosed()
          .pipe(
            take(1),
            switchMap((success: boolean) => {
              if (success) {
                // special handling
    
                return this.localStorageService.save(objectToSave);
              }
              return of(false);
            })
          );
      } else {
        return this.localStorageService.save(objectToSave);
      }
    }
    

    此外,您的LocalStorageManagerService 应该只在订阅save 的返回时进行实际保存,而不仅仅是在调用save 时:

    save(objectToSave): Observable<boolean> {
      return defer(() => {
        if (this.storageAvailable()) {
          localStorage.setItem(objectToSave.id, JSON.stringify(objectToSave));
          return of(true);
        }
    
        console.error('local storage not available or disabled');
        return of(false);
      });
    }
    

    【讨论】:

    • 谢谢安德烈,这行得通!我会在一分钟内接受答案(不知何故我不允许这样做)。更感谢您让我意识到我的保存方法中的问题并提供解决方案!
    猜你喜欢
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 2020-04-09
    • 2021-01-20
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多