异步管道未订阅 Observable Angular
async pipe not subscribing to Observable Angular
在 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...)。
谁能解释一下这是怎么回事?
可以和你的combineLatest有关。检查两个 observables 是否都在发射数据。
Combine最新定义:
Be aware that combineLatest will not emit an initial value until each
observable emits at least one value. This is the same behavior as
withLatestFrom and can be a gotcha as there will be no output and no
error but one (or more) of your inner observables is likely not
functioning as intended, or a subscription is late.
您可以使用 startWith 运算符为可观察对象设置一些初始值。
最后,是路由器事件没有让 observable 完成。
显然,如果我将导航从模板移动到 .ts 并订阅 ActivatedRoute.params
而不是 Router.events
。
所以,父组件得到:
navigateToDetails(id: string): void {
this.router.navigate(['/myRoute', id]);
}
而不是在模板中使用 routerLink
:
<a [routerLink]="['/myRoute']" [queryParams]="{id: item.id}">
然后,在 DataDetailsComponent
我可以做:
constructor(dataService: DataService, route: ActivatedRoute) {
this.data$ =
combineLatest([dataService.getDataObservable(), route.params])
.pipe(map(([data, params]) => data.filter(c => c.id === params['id'])[0]));
}
此时我无法解释原因。
在 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...)。
谁能解释一下这是怎么回事?
可以和你的combineLatest有关。检查两个 observables 是否都在发射数据。
Combine最新定义:
Be aware that combineLatest will not emit an initial value until each observable emits at least one value. This is the same behavior as withLatestFrom and can be a gotcha as there will be no output and no error but one (or more) of your inner observables is likely not functioning as intended, or a subscription is late.
您可以使用 startWith 运算符为可观察对象设置一些初始值。
最后,是路由器事件没有让 observable 完成。
显然,如果我将导航从模板移动到 .ts 并订阅 ActivatedRoute.params
而不是 Router.events
。
所以,父组件得到:
navigateToDetails(id: string): void {
this.router.navigate(['/myRoute', id]);
}
而不是在模板中使用 routerLink
:
<a [routerLink]="['/myRoute']" [queryParams]="{id: item.id}">
然后,在 DataDetailsComponent
我可以做:
constructor(dataService: DataService, route: ActivatedRoute) {
this.data$ =
combineLatest([dataService.getDataObservable(), route.params])
.pipe(map(([data, params]) => data.filter(c => c.id === params['id'])[0]));
}
此时我无法解释原因。