我有以下 Angular 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() observable 可能会多次获取新数据,但 this.route.queryParams 不会获取新数据,除非查询参数发生变化
但是,通过设置调试断点,我发现当查询参数“stufId”更新时,“stuffId”的初始值是我所期望的(UUID),但是当内部订阅(状态服务)更新“stuffId”时,外部范围中的“stuffId”值变为“未定义” - 然后另一个状态更新会再次使用该 id 重新填充它。这会导致“口吃”;在 View 中。
我不明白内部作用域如何改变外部作用域,因为内部作用域永远不会访问“stuffId”。有些 rxjs 的东西我不明白还是什么?
最佳答案
I do not understand how the outer scope is getting changed by the inner scope since 'stuffId' is never accessed by the inner scope. Some rxjs thing I don't understand or something?
这是因为 this.route.queryParams
多次发出一个值。
每次发出一个值时,都会对 this.service.getState()
进行新订阅,并超时内部 subscribe()
将触发重叠调试中断。从调试器的 Angular 来看,您可能没有意识到您正在同时调试两个或多个订阅。
由于您执行此操作 this.data = state
或 this.data = SpecificState
, View 模板闪烁。
我建议您了解如何在 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);
关于javascript - 为什么当内部订阅发生变化时,外部订阅范围内的变量集也会发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56307038/