如何创建依赖Angular @Input()值的只读Observable?
如何优雅实现依赖Angular组件@Input()值的Observable字段?
我经常遇到这样的场景:需要定义一个依赖Angular组件@Input()值的Observable字段,比如@Input() id: string。
我原本希望写出这样的代码:
export class DataViewerComponent implements OnInit { @Input() id: string; readonly data$ = this.dataService.byId$(this.id); constructor(private dataService: DataService) { } ... }
但这种写法无法生效,因为id字段要在构造函数之后、OnInit钩子之前才会被赋值。
我通常的解决方案是创建一个私有Subject(例如_id$):
export class DataViewerComponent implements OnInit { @Input() id: string; private _id$ = new ReplaySubject<string>(1); readonly data$: Observable<Data> = this._id$.pipe( switchMap(id => this.dataService.byId$(id)) ); constructor(private dataService: DataService) { } ngOnInit() { this._id$.next(this.id); } }
这个方案不算差,但有没有更好的实现方式?我曾考虑添加一个管道来等待Angular生命周期初始化完成后再执行:
readonly data$ = of(onNgInit).pipe(switchMap(() => this.dataservice.byId$(this.id)))
另外,下面这种写法有时也能生效:
readonly data$ = of(null).pipe(switchMap(() => this.dataservice.byId$(this.id)))
但这似乎存在竞态条件。
编辑说明:这并非竞态条件。通过of(null)创建的管道,switchMap中的表达式要等到Observable收到订阅后才会执行。只要订阅是在OnInit钩子中或通过HTML模板的async管道完成的,此时id的值就已经存在了。
内容的提问来源于stack exchange,提问作者Kevin Dufendach
相关产品推荐
相关产品推荐

