1

在 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$. 另一方面,当我做 place 时this.data$.subscribe();,控制台得到正确的输出,但视图仍然是空的(挂在Loading...上)。

谁能解释发生了什么?

4

2 回答 2

0

最后,是路由器事件没有让 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]));
    }

在这一点上,原因超出了我的范围。

于 2021-05-30T20:50:57.697 回答
0

可以与您的 combineLatest 相关。检查以查看两个可观察对象都在发出数据。

结合最新定义:

请注意,在每个 observable 发出至少一个值之前, combineLatest 不会发出初始值。这与 withLatestFrom 的行为相同,并且可能是一个陷阱,因为没有输出也没有错误,但是您的一个(或多个)内部可观察对象可能无法按预期运行,或者订阅延迟。

您可以使用 startWith 运算符为可观察对象设置一些初始值。

于 2021-05-29T00:17:40.350 回答