简体   繁体   English

异步 pipe 未订阅 Observable Angular

[英]async pipe not subscribing to Observable Angular

In Angular (v12) I've got a following component (using dummy variable names):在 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
    }
}

And its template:及其模板:

<div *ngIf="data$ | async as data; else loading">
    <img [src]="data.url" [alt]="data.name">
</div>
<ng-template #loading>Loading...</ng-template>

Data is not being rendered, and the browser console is empty if I don't actually subscribe to the data$ .没有呈现数据,如果我实际上没有订阅data$ ,则浏览器控制台为空。 On the other hand, when I do place this.data$.subscribe();另一方面,当我放置this.data$.subscribe(); , console gets correct output, but the view is still empty (hangs on Loading... ). ,控制台得到正确的 output,但视图仍然是空的(挂起加载... )。

Can anyone explain what's going on?谁能解释发生了什么?

can be related to your combineLatest.可以与您的 combineLatest 相关。 check to see both observables are emitting data.检查以查看两个可观察对象都在发出数据。

CombineLatest definition:结合最新定义:

Be aware that combineLatest will not emit an initial value until each observable emits at least one value.请注意,在每个 observable 发出至少一个值之前, combineLatest 不会发出初始值。 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.这与 withLatestFrom 的行为相同,并且可能是一个陷阱,因为不会有 output 并且没有错误,但是您的一个(或多个)内部可观察对象可能无法按预期运行,或者订阅延迟。

you can use startWith operator to set some initial value for observables.您可以使用 startWith 运算符为可观察对象设置一些初始值。

In the end, it was the router event that was not letting observable complete.最后,是路由器事件没有让 observable 完成。 Apparently, it works if I move navigation from template to.ts and subscribe to ActivatedRoute.params instead of Router.events .显然,如果我将导航从模板移动到.ts 并订阅ActivatedRoute.params而不是Router.events ,它会起作用。

So, the parent component gets:所以,父组件得到:

navigateToDetails(id: string): void {
    this.router.navigate(['/myRoute', id]);
}

instead of using routerLink in template:而不是在模板中使用routerLink

<a [routerLink]="['/myRoute']" [queryParams]="{id: item.id}">

And then, on DataDetailsComponent i can do:然后,在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]));
    }

Reasons why are beyond me at this point.在这一点上,原因超出了我的范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM