Angular2组件显示一些对象。除了基础对象信息之外,还需要通过返回Observable的服务加载额外的数据并且速度很慢。
对象信息的基础部分应立即显示,并且额外数据一旦可用。
这样的事情:
SomeObjectComponent {
someObject: SomeObject;
extraData: ExtraData;
@Input()
set item(v: SomeObject) {
this.someObject = v;
backendService.getExtraData(v.id)
.subscribe(d => this.extraData = d);
}
}
// in the template
<some-object [item]="currentlySelected"></some-object>
当加载速度很慢且用户在SomeObject
的不同值之间导航时,异步加载可能会加载并为当前项目分配错误的extraData
。
解决这个问题的最佳方法是什么?如果每次都需要加载多个额外的数据项(并且每次加载时都会出现),该怎么办?
答案 0 :(得分:1)
如果我理解正确的话,基本上你要找的是一种取消“旧的”休息电话的方法,只要选择了新项目 - &gt; rxjs-way将使用.takeUntil(...)
SomeObjectComponent implements OnDestroy {
// to clean up any open subscriptions it is helpful to have a destroy-event
private destroyed$: Subject<any> = new Subject<any>();
// your vars
someObject: SomeObject;
extraData: ExtraData;
@Input()
set item(v: SomeObject) {
this.someObject = v;
this.loadExtraData$.next(v.id);
}
// a trigger to load extra data
private loadExtraData$: Subject<number> = new Subject<number>(); // type "number" is just an assumption, this can be whatever type "v.id" is
// the stream to load extra data
private extraData$: Observable<any> = this.loadExtraData$
.takeUntil(this.destroyed$) // when the component is destroyed this will ensure that any open subscription will be closed as well to prevent memory leaks
.switchMap(id => {
return this.backendService
.getExtraData(id)
.takeUntil(this.loadExtraData$); // will discard the rest-call the next time loadExtraData$ is triggered (if it is still running)
})
.do(extraData => this.extraData = extraData) // if you only need the data in the template, then don't use this line and use the "| async"-pipe instead
.share();
// this is called by the angular2-lifecycle, when the component is removed
ngOnDestroy() {
this.destroyed$.next();
}
}
如果您只需要模板中的额外数据,那么您可能想要使用async
- pipe:
<span>Some extra data: {{(extraData$ | async)?.someAttribute}}</span>
作为一个小小的侧面说明并稍微偏离主题:不加载组件中的额外数据,但在组件外部并使用@Input()
是更好的做法对于额外数据,原因有很多:
@Input()
和@Output()
s ,则组件在不同的上下文中更容易重用
话虽如此,在不了解您当前的架构的情况下,这可能会带来更大的重构,这可能不值得花时间,但这是未来应用需要考虑的事项。