我有以下6号角代码:
ngOnInit() {
this.route.queryParams.subscribe((params: Params) => {
const stuffId: string = params.stuffId;
this.service.getState().subscribe((state) => {
if (stuffId) {
const specificStuff: Array<Stuff> = state.stuff.filter((s) => s.id === stuffId);
const specificState: State = {
stuff: specificStuff,
tableData: this.service.getTableModel(specificStuff),
chartData: this.service.getChartModel({ stuff: specificStuff }),
hasAssetId: true,
};
this.data = specificState;
} else {
this.data = state;
}
});
});
}
可观察到的this.service.getState()可能会多次获取新数据,但是this.route.queryParams不会获取新数据,除非查询参数发生更改
但是,通过设置调试断点,我看到查询参数'stufId'更新时,'stuffId'的初始值是我期望的值(UUID),但是当内部订阅(状态服务)更新了'外部作用域中的stuffId的值变为“未定义”-然后另一个状态更新再次用id填充它。这造成了“口吃”;在视图中。
我不明白内部作用域如何改变外部作用域,因为内部作用域从未访问过'stuffId'。一些我不理解的rxjs东西?
答案 0 :(得分:1)
我不明白内部作用域如何改变外部作用域,因为内部作用域从未访问过'stuffId'。一些我不理解的rxjs东西?
这是因为this.route.queryParams
发出一个以上的值。
每次发出值时,都会为this.service.getState()
进行 new 订阅,内部subscribe()
超时将触发重叠调试中断。从调试器的角度来看,您可能没有意识到自己正在同时调试两个或多个订阅。
this.data = state
或this.data = specificState
执行此操作后,视图模板就会闪烁。
我建议您学习如何在Rxjs中使用switchMap
和mergeMap
运算符,而不是从另一个订阅中调用subscribe
。您只应为即将完成的短暂可观察性调用内部订阅。
this.route.queryParams
.pipe(
map((params: Params) => params.stuffId),
switchMap(stuffId => combineLatest([
of(stuffId),
this.service.getState()
])),
map(([stuffId, state]) => {
if (!stuffId) {
return state;
}
const specificStuff: Stuff[] = state.stuff.filter((s) => s.id === stuffId);
return {
stuff: specificStuff,
tableData: this.service.getTableModel(specificStuff),
chartData: this.service.getChartModel({stuff: specificStuff}),
hasAssetId: true,
};
})
).subscribe(data => this.data = data);