当前代码正在尝试使用 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>
回答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 更改时触发。