我正在尝试找到一种更有效/类似于rxjs的方式来实现这一目标。下面的代码有效,但是必须有更好的方法。
ngOnInit() {
this.activatedRoute.params.subscribe(({ bookId }) => {
this.characters$ && this.characters$.unsubscribe();
this.characters$ = this.fetchCharactersByBook(bookId)
.subscribe(characters => this.characters = characters);
});
}
基本上,我只是在听路由参数的更改,并订阅由Characters
来获取bookId
的请求。随着对路由参数的每次更改,我都需要首先从上一个请求中退订以获取字符。
是否有更好,更优雅的方法来实现这一目标?
有时RxJS让所有操作员都感到头疼。非常感谢您的帮助。
答案 0 :(得分:1)
您实际上不需要unsubscribe
。您可以使用switchMap
运算符将params对象转换为字符列表。而且,您应该通过使用async
管道将其在模板中展开来强制性地管理预订。
创建可观察的角色。
this.characters$ = this.activatedRoute.params
.pipe(switchMap(parms => this.fetchCharactersByBook(parms.bookId));
创建observable
后,请使用异步管道将characters
的模板引用替换为(characters$ | async)
,以对其进行解包。该组件将在拆解过程中处理characters$
可观察到的内容。\
答案 1 :(得分:1)
switchMap可用于从外部可观察到内部可观察的切换,并具有在下一个值发出时取消订阅到内部可观察的优点。取消订阅将取消之前仍待处理的Http请求。
您可以在模板中使用*ngIf="o$ | async as o"
语法,以避免必须订阅并将变量分配给本地属性。 as o
将声明一个带有发射值的模板变量。
如果要在同一模板中多次使用o$ | async
,而又不发出多个Http请求,则可以使用shareReplay。
@Component({
...
template: `<ng-container *ngIf="characters$ | async as characters">
{{characters | json}}
</ng-container>`
})
export class ExampleComponent {
characters$: Observable<Character[]>;
public ngOnInit() {
this.characters$ = this.activatedRoute.params.pipe(
pluck('bookId'),
switchMap(bookId => this.fetchCharactersByBook(bookId)),
shareReplay(1)
);
}
}