我有一个可观察量,它在创建时需要有一个初始值,但它也需要侦听事件,如果发生变化,它应该重新填充来自服务器的数据。看起来很简单,但我找不到一种优雅的方式来做到这一点。
所以这就是场景,我有一个绑定到异步数组可观察的形式的选择,如下所示:
<mat-select>
<mat-option *ngFor="let unit of units$ | async"
[value]="unit.unitCode">
{{ unit.unitCode }}
</mat-option>
</mat-select>
首次初始化组件时,它可能处于 2 种状态中的 1 种:
- 来自数据库的记录,我已经有提交的表单的有效数据。
- 一条新记录,其中 units$ 仅在另一个文件获得其值后才应填充。
在任何一种情况下,更改另一个文件的值都应该获取单位$的新值。
这是我目前所拥有的:
ngOnInit(): void {
if (this.form.controls['itemID'].value) {
this.units$ = of([Object.assign(new Unit(), {
unitCode: 'U1'
})]);
}
this.units$ = this.form.controls['itemID'].valueChanges
.pipe(
switchMap((term: number ) => {
return this.service.getById(term);
}));
}
当然,这样做意味着我分配给单位$的初始值将不存在,因为我重新分配了可观察量。 我实际上正在寻找一种类似于startWith
的事情的方式,而无需实际调用服务,但仍然获得一个列出更改的可观察量。
所需行为的示例:组件保存来自数据库的记录。
- 除非用户更改"itemID",否则没有理由从服务获取数据。
- units$ 有一个"unit"数组,只有一个记录中的单元。
- 如果用户更改了"itemID",则units$应从服务中获取新值。
看起来像是使用startWith
运算符的完美用例。
在这里,试一试:
ngOnInit(): void {
this.units$ = this.form.controls['itemID'].valueChanges
.pipe(
startWith([Object.assign(new Unit(), {
unitCode: 'U1'
})]),
switchMap((term: number) => this.service.getById(term)));
}
还没有测试过。但是不要看到它不应该工作的原因。
如果它没有:),请告诉我
希望这有帮助。
你可以使用Subject
,这是一种可观察量。与常规可观察量不同,您可以使用其next()
方法手动将数据推送到其中。像这样:
units$ = new Subject<[]>();
ngOnInit(): void {
if (this.form.controls['itemID'].value) {
this.units$.next([Object.assign(new Unit(), {
unitCode: 'U1'
})]);
}
this.form.controls['itemID'].valueChanges
.pipe(
switchMap((term: number ) => {
this.units$.next(this.service.getById(term));
}));
}