如果使用异步管道可观察到错误,则角度显示模板

Sam*_*lis 7 javascript rxjs angular

我有一个 API 调用,它可能会返回一些数据,或者如果不存在数据,则可能会返回错误的内容。如果有数据,我想tap退出流并执行一些副作用,但如果错误,我希望没有副作用发生,但仍然显示我的模板代码。

我正在使用异步管道来获取模板中的数据,但如果数据错误,它将不会显示。

ngIf我已经看到了用对象包装 的技术,因此它的计算结果为真,但这似乎不是我的代码的正确解决方案。

我的模板:

<form *ngIf="loadedData$ | async">
  ...
</form>
Run Code Online (Sandbox Code Playgroud)

我的课:

loadedData$: Observable<boolean>;

ngOnInit(): void {
  this.loadedData$ = this.getCurrentBranding().pipe(
    tap(branding => {
      if (branding) {
        // Do side effects
      }
    }),
    // current hack to make the template show
    map(() => true)
  );
}

private getCurrentBranding(): Observable<Branding> {
  // API call, may return an object, or null
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*nez 2

我已经养成了为我的组件使用单个可观察对象的习惯,该可观察对象合并多个流,将它们组合成一种状态。通常这涉及 扫描操作符,但在这种情况下没有必要(尽管也许您也想合并这些副作用)。

在下面的代码中,getCurrentBranding将在组件中的异步管道订阅时执行。为了防止多次执行,您可以使用一个根元素来使用 Angular 的表达式将发射转换为模板变量。或者,您可以使用shareReplay

startWith运算符用于提供初始值,因此根元素将始终显示。该表单最初将被隐藏,直到从 api 返回结果为止。数据将来自相同的可观察对象,并从根元素创建的模板变量进行访问。

this.state$ = this.getCurrentBranding().pipe(
  tap(branding => { /* Do side effects */ ),
  map(data => ({ data, isLoaded: true}),
  startWith(({ data: [], isLoaded: false})
);
Run Code Online (Sandbox Code Playgroud)
<ng-container *ngIf="(state$ | async) as state">
  <form *ngIf="state.isLoaded">
    <!-- ... -->
  </form>
  <ol *ngFor="let o of state.data">
    <!-- ... -->
  </ol>
</ng-container>
Run Code Online (Sandbox Code Playgroud)