angular - 来自可观察订阅的 Angular 7 奇怪行为
问题描述
我有一个代码来处理来自 observable 的一些数据,这个 observable 是通过 @Input 注释获取的,我订阅了我的 NgOnInit() 中的 observable,一切正常,但我需要添加代码以减少处理数据的时间,这是一个数组数组,我的数据如下所示:
[ ['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,当 observable 接收到新值时,再次执行第 43 行,执行第 43 行时更新 this.dataSetHolder 的值,那不应该发生,它应该只在第 64 行更新。
有人明白那里发生了什么吗?
请注意,从最后一张图片到下一张我在调试时没有点击继续,我仍然在第 44 行
我也尝试将第 64 行更改为此
this.dataSetHolder = Object.assign([], data);
因为我认为它可能是由javascript引起的,因为当我这样做时 this.dataSetHolder = data; 它实际上并没有传递对象,只是传递了引用,但它仍然没有工作。
解决方案
我的最终代码如下所示:
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;
到我的代码中。