angular - 如何在模板中为 async pipe 初始化一个 observable 试图模仿订阅中的分配?

当前代码正在尝试使用 async pipe 方法,而不是在订阅中使用分配。但是,如果服务中发生延迟,则初始 value 不会在模板中呈现,当数据准备好时 value 正在按预期呈现,我试图模仿呈现时呈现的渲染行为使用this.title2。

组件:

title$: Observable<string> = of('Default Title'); // I am not sure if this assignation is right
title2 = 'Default Title 2';

constructor(private sampleService: SampleService) {}

// Load title has a delay in the response
this.title$ = this.sampleService.loadTitle();

this.sampleService.loadTitle().subscribe((title) => {
  this.title2 = title; // the assignation 
});

模板:

<h4>{{ title$ | async }}</h4>
<h4>{{ title2 }}</h4>

https://stackblitz.com/edit/angular-ivy-dhpvpb?file=src%2Fapp%2Fcomponents%2Fcontainer%2Fcontainer.component.ts

回答1

我认为您想使用 https://www.learnrxjs.io/learn-rxjs/operators/combination/startwith 来执行 observable 的初始值。尝试将代码更改为此,它可以工作。

this.title$ = this.sampleService
      .loadTitle()
      .pipe(startWith('Default Title'));

回答2

有几种方法可以解决此问题,但鉴于您提供的代码,您可以使用 switchMap 运算符,如下所示:

this.title$ = this.sampleService.loadTitle(); 更新为 this.title$.pipe(switchMap(() => this.sampleService.loadTitle()));

您当前正在做的是用不同的 value 覆盖 title$ 属性。 switchMap 使得每次第一个 observable 发出一个 value (在您的情况下,这只发生一次与您的 of('Default Title') 一起)它会转身并创建另一个 observable 然后它将观察发出values。

回答3

您可以使用 ng-container 订阅您的 observable 并重命名它,以便在数据准备好时,您可以简单地将其用作模板中的常规变量。 https://stackblitz.com/edit/angular-ivy-4f77tz?file=src/app/components/container/container.component.ts

容器.component.ts

export class ItemsComponent implements OnInit {
  @Input() name: string;
  items$: Observable<string[]>;
  title$: Observable<string>;

  constructor(private sampleService: SampleService) {}

  ngOnInit() {
    this.title$ = this.sampleService.loadTitle();
    this.items$ = this.sampleService.loadItems();
  }
}

container.component.html

<ng-container *ngIf="title$ | async as title">
  <h4>{{ title }}</h4>
</ng-container>

<ng-container *ngIf="items$ | async as items">
  <list *ngIf="items.length" [items]="items"></list>
</ng-container>

请记住,无论您在哪里使用异步一词,它都是一个新订阅。

如果您在模板中多次在同一个 observable 上使用 async pipe,则您正在创建多个订阅。

如果您希望使用与服务调用不同的起始 value ,使用 startWith 运算符也是一个不错的选择。使用 startWith 的好地方是 formControl valueChanges observable 因为它没有起始 value 并且仅在 value 更改时触发。

相似文章