Angular 角度路由和RxJs订阅共享
编辑:显然,Angular 角度路由和RxJs订阅共享,angular,rxjs,Angular,Rxjs,编辑:显然,shareReplay方法也很好。我不明白为什么,但是,鉴于操作员的描述。如果有人愿意解释原因,我们将不胜感激 我目前有一个组件,通过路由进行管理,其模板如下 <app-one [attr]="entity$ | async"></app-one> <app-two [attrOne]="(entity$ | async)?.id" [attrTwo]="(entity$ | async)?.name" ></app-two>
shareReplay
方法也很好。我不明白为什么,但是,鉴于操作员的描述。如果有人愿意解释原因,我们将不胜感激
我目前有一个
组件
,通过路由进行管理,其模板如下
<app-one [attr]="entity$ | async"></app-one>
<app-two
[attrOne]="(entity$ | async)?.id"
[attrTwo]="(entity$ | async)?.name"
></app-two>
由于我使用了三次
async
管道,service.getEntity
被调用了三次(我可以看到三次HTTP调用)
如何缓解此问题?正在添加
shareReplay(1)
可接受的解决方案?我不这么认为,因为这会打乱路线
编辑:我的组件都是
OnPush
,订阅并将结果存储为类属性意味着必须检测更改
,我一点也不喜欢。我认为您可以使用ng容器
应用async
管道将结果存储在变量中,然后在组件中使用它,例如:
<ng-container *ngIf="entity$ | async as entity"
<app-one [attr]="entity"></app-one>
<app-two
[attrOne]="entity?.id"
[attrTwo]="entity?.name"
></app-two>
</ng-container>
this.entity$ = new Observable<Entity>(observer => {
observer.next(null);
this.route.paramMap.pipe(
map(params => params.get('entityId')),
mergeMap(entityId => this.service.getEntity(entityId)),
).subscribe(e => {
observer.next(e);
observer.complete();
}, () => {
observer.complete();
});
});
{
observer.next(空);
this.route.paramMap.pipe(
map(params=>params.get('entityId'),
mergeMap(entityId=>this.service.getEntity(entityId)),
).订阅(e=>{
观察员:下一个(e);
observer.complete();
}, () => {
observer.complete();
});
});
希望有帮助 一个选项是订阅
this.route.paramMap
,并将结果存储在实体属性上(在这种情况下,实体的类型将不可观察)。另一个选项是使用ngIf:*ngIf=“(entity$| async)as entity”
@Igor将可观察值展开为本地模板值,例如,当路由参数更改时,难道它不会简单地使用以前计算的值吗?当路由参数改变时,组件不会被重新加载,从而对ngOnInit
进行新调用吗?@Igor否,显然组件
不会被重新创建(如果使用角度路由)。@IgorshareReplay
似乎工作正常,即使组件没有重新加载,老实说,我不知道为什么。谢谢你的建议!如果我想显示那些模板组件,即使该值不存在,该怎么办?我的意思是,*ngIf
将隐藏它们,直到发出第一个有效值,对吗?我考虑的另一个选项是subscribe
ing并将结果存储为类属性。但是,我的组件都是推送的,所以我必须检测更改,这是我不喜欢的。@LppEdd您应该更新您的问题以包含以下信息:“我的组件都是推送的,所以我必须检测更改,这是我不喜欢的。”您可以创建自己的Observable
并发出第一个值null
,然后订阅paramMap
,并从服务中给出值,或者如果出现错误,则发出null
happens@dcg嗯,我想我明白了,但我不是一个角度/RxJs专家。你能给我一个小片段来演示一下吗?不需要太详细,只要一个草图。@LppEdd我编辑了我的答案。我没有测试过,但我以前做过类似的事情。
<ng-container *ngIf="entity$ | async as entity"
<app-one [attr]="entity"></app-one>
<app-two
[attrOne]="entity?.id"
[attrTwo]="entity?.name"
></app-two>
</ng-container>
this.entity$ = new Observable<Entity>(observer => {
observer.next(null);
this.route.paramMap.pipe(
map(params => params.get('entityId')),
mergeMap(entityId => this.service.getEntity(entityId)),
).subscribe(e => {
observer.next(e);
observer.complete();
}, () => {
observer.complete();
});
});