Почему переменная, заданная в области внешней подписки, изменяется при изменении внутренней подписки - PullRequest
0 голосов
/ 25 мая 2019

У меня есть следующий угловой код 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 'во внешней области видимости становится неопределенным - тогда другое обновление состояния снова заполняет его идентификатором. Это вызывает «заикание»; в представлении.

Я не понимаю, как внешняя область видоизменяется внутренней областью, так как внутренняя область никогда не получает доступ к «stuffId». Какая-то вещь, которую я не понимаю или что-то в этом роде?

1 Ответ

1 голос
/ 25 мая 2019

Я не понимаю, как внешняя область видоизменяется внутренней областью, так как внутренняя область никогда не получает доступ к 'stuffId'.Что-то, что я не понимаю или что-то в этом роде?

Это потому, что this.route.queryParams выдает значение более одного раза.

Каждый раз, когда значение выдается new подписка сделана на this.service.getState(), и со временем внутренний subscribe() вызовет перекрывающихся разрывов отладки.С точки зрения отладчика вы можете не осознавать, что отлаживаете две или более подписок одновременно.

Поскольку вы делаете это this.data = state или this.data = specificState, шаблон представления мигает .

Я рекомендую вам узнать об использовании switchMap и операторов mergeMap в Rxjs вместо вызова 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);
...