【发布时间】:2021-05-28 21:53:09
【问题描述】:
在 Angular (v12) 中,我有以下组件(使用虚拟变量名称):
export class DataDetailsComponent {
data$: Observable<MyDataModel>;
constructor(dataService: DataService, route: ActivatedRoute, private router: Router) {
this.data$ =
combineLatest([dataService.getDataObservable(), router.events])
.pipe(
filter(([,event]) => event instanceof ActivationEnd),
tap(([data, event]) => console.log((<ActivationEnd>event).snapshot.queryParams['id'])),
map(([data, event]) => data.filter(c => c.id === (<ActivationEnd>event).snapshot.queryParams['id'])[0]),
tap(dataItem => console.log(dataItem))
);
this.data$.subscribe(); // console.logs don't work without this
}
}
及其模板:
<div *ngIf="data$ | async as data; else loading">
<img [src]="data.url" [alt]="data.name">
</div>
<ng-template #loading>Loading...</ng-template>
如果我实际上没有订阅data$,则不会呈现数据,并且浏览器控制台为空。另一方面,当我放置 this.data$.subscribe(); 时,控制台会得到正确的输出,但视图仍然是空的(挂在 Loading... 上)。
谁能解释这是怎么回事?
【问题讨论】:
-
也许你的 observable 返回了假值,使得 *ngIf 评估为假?
-
尝试
combineLatest([dataService.getDataObservable(), router.events]).subscribe(console.log))获取更多信息 -
@AllanJuan 但是当我手动订阅时,我从
tap(console.log(...))得到了非常真实的值... -
可能是一个长镜头,但值得尝试将设置代码移动到 ngOnInit 以确保它与某些未初始化的组件状态无关。如果将真实的 observable 替换为 dummy of(true) 会发生什么?
-
另一个想法。首先,请注意构造函数中的订阅和 ngFor 中的订阅将在不同的时间发生,因此从 combineLatest 返回的值可能不同。尝试在过滤器之前再次点击 - 当 ngFor 订阅时,如果 combineLatest 没有发出,或者它被过滤掉,那么你会看到你所看到的。您也可以尝试“startWith”来检验假设。
标签: angular rxjs angular-router angular2-observables async-pipe