Angular 7 Странное поведение из наблюдаемой подписки - PullRequest
0 голосов
/ 30 января 2020

У меня есть код для обработки некоторых данных, которые поступают из наблюдаемой, эта наблюдаемая получается через аннотацию @Input, я подписываюсь на наблюдаемую внутри моего NgOnInit (), все работало нормально, но мне нужно было добавить код в сократить время обработки данных, представляющих собой массив массивов, мои данные выглядят так:

[['id1', объект, объект], ['id2', объект, объект]]

Таким образом, чтобы сократить время обработки, я создал переменную, которая будет содержать предыдущее значение Observable для последующей обработки, и я сравниваю предыдущие данные с новыми данными и обновляю только те данные, которые изменились, мой код выглядит следующим образом :

 private dataSetHolder: Array<any> = [];

constructor() { }


ngOnInit() {
    this.dataSet$.subscribe(data => { //line 43
        console.log('inicio: ', this.dataSetHolder);
        data.forEach(array => {
            const dataNoId = Object.assign([], array);
            const id = array[0];
            dataNoId.shift();
            let pacote: Package = { eixo_x: [], eixo_y: [] };
            if (this.dataSetHolder.length === 0) {
                pacote = this.separaDados(dataNoId, id, pacote);
                this.loadData(pacote);
            } else {
                this.dataSetHolder.forEach(arrayHolder => {
                    if (id === arrayHolder[0]) {
                        if (array.length > arrayHolder.length) {
                            pacote = this.separaDados(dataNoId, id, pacote);
                            this.loadData(pacote);
                        }
                    }
                });
            }
        });
        this.dataSetHolder = data; //line 64
    });
}

Когда строка 64 выполняется, текущее значение данных передается this.dataSetHolder, когда наблюдаемое получает новое значение, строка 43 выполняется снова, а когда строка 43 выполняется, значение this.dataSetHolder обновляется, это не должно происходить, оно должно обновляться только в строке 64.

Кто-нибудь понимает, что происходит там?

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

Обратите внимание, что от этого последнего изображения до следующего, которое я не нажал, продолжить отладку, я все еще на линии 44

inserir a descrição da imagem aqui

Я также попытался изменить строку 64 на эту

            this.dataSetHolder = Object.assign([], data);

Поскольку я думал, что это может быть вызвано javascript, потому что, когда я делаю это .dataSetHolder = data; фактически он не передает объект, только ссылку, но он все еще не работает.

1 Ответ

0 голосов
/ 01 февраля 2020

Мой окончательный код выглядит так:

    ngOnInit() {
    this.dataSet$.subscribe(data => {
        data.forEach(array => {
            const dataNoId = Object.assign([], array);
            const id = array[0];
            dataNoId.shift();
            let pacote: Package = { eixo_x: [], eixo_y: [] };
            if (this.dataSetHolder.length === 0) {
                pacote = this.separaDados(dataNoId, id, pacote);
                this.loadData(pacote);
            } else {
                this.dataSetHolder.forEach(arrayHolder => {
                    if (id === arrayHolder[0]) {
                        const length = Object.keys(arrayHolder).length;
                        if (array.length > length) {
                            pacote = this.separaDados(dataNoId, id, pacote);
                            this.loadData(pacote);
                        }
                    }
                });
            }
        });
        this.dataSetHolder = [];
        data.forEach(dataItem => this.dataSetHolder.push({... dataItem}));
    });
}

Благодаря комментарию bmtheo я решил проблему, как он объяснил, даже использования Object.assign () для копирования данных недостаточно, так как мои данные - это массив массивов, когда я использовал Object.assign (), я скопировал первый уровень моего массива, но массивы второго уровня не копировались, на них ссылались, поэтому данные меняются каждый раз, когда доступно новое значение.

Решение состоит в том, чтобы очистить мой массив и скопировать в него каждый вложенный массив. в дополнение к этому мне пришлось изменить способ получения длины arrayHolder, поскольку он больше не интерпретировался как массив, он обрабатывался как объект, который не влияет на остальную часть кода, поэтому Я добавил это const length = Object.keys(arrayHolder).length; в свой код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...