javascript - 为什么当内部订阅发生变化时,外部订阅范围内的变量集也会发生变化

标签 javascript angular rxjs observable state

我有以下 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 = statethis.data = SpecificState, View 模板闪烁

我建议您了解如何在 Rxjs 中使用 switchMapmergeMap 运算符,而不是从另一个订阅内部调用 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/

相关文章:

javascript - 谷歌图表传递分段值

javascript - 外部点击在 angularjs 中不起作用

javascript - 为什么这有效?清除用作表单的 javascript 对象

javascript - Django + Django-Pipeline with Javascript "Require"

angular - 使用 angular 5 分析 asp.net core 2 (web api)

javascript - 如何将自定义库事件(即 Google map 事件)转换为 RxJS 中的 Observable 流?

angular - ionic 2 中带有异步管道的重复 http 请求

angular - RXJS如何延迟每个可观察的(http请求)并合并所有请求输出

javascript - 在不使用 disabled 的情况下保持 Material Slide Toggle 处于开启或关闭状态

css - 编辑 Angular Material 的表格单元格填充