如何在不造成大量滞后的情况下观察一系列对象的变化?
How to watch for changes in an array of objects without causing massive lag?
我觉得 Angular 2 缺少 Angular 1 所具有的一些东西,其中之一就是 $watch
函数。
OnChanges
和 DoCheck
应该替换 $watch
但我无法使用其中任何一个来获得所需的结果。 OnChanges
无法监听对象,因此在这种情况下没有用,虽然 DoCheck
完成了这项工作,但它会导致巨大的滞后,因为一旦发生变化它似乎就会变得疯狂。
这里我有一个组件,它有一堆复选框,每个复选框切换都会导致将一个值添加到数组,而不是默认的 true/false
功能。
在此组件中我需要注意的是复选框的 isDisabled
状态,因此每次更改时我都需要更新 checkbox
的 isChecked
状态。
就像我说的,它有效,但它在每个复选框切换时都有 2-3 秒的延迟,尽管只有 5 个复选框。最好我不希望每次切换复选框时循环到 运行,而是仅当复选框的 isDisabled
状态发生变化时才循环。
编辑:有人告诉我 Observable
可以在这里完成这项工作,但我找不到任何将其应用于对象数组的示例,例如这个。它还需要在不手动调用其 next()
方法的情况下触发,因为它必须侦听对正在发送的数组的外部更改。
编辑 2:我创建了一个不显示延迟的 plunkr,可能是因为在我的应用程序中我还有其他可能对延迟有影响的东西。但是,plunkr 清楚地表明似乎有问题,因为我在 ngDoCheck()
函数中放置了一个 console.log(true)
并且它 运行 是很多次。这不是有意的,如果是,那就太奇怪了。
这里是 plunkr:https://plnkr.co/edit/dJVnqbrredDyWTXNDzDK?p=preview
我该怎么做?
export class FormCheckboxMultipleComponent implements OnInit, DoCheck {
@Input() model: Array<any>;
@Output('modelChange') onModelChange: EventEmitter<any> = new EventEmitter();
@Output() callback: EventEmitter<any> = new EventEmitter();
constructor(private _globals: GlobalVariablesService) {
this.ns = _globals.ns;
}
ngOnInit() {
this.model = this.model || [];
}
ngDoCheck() {
for (let checkbox of this.checkboxes) {
if (checkbox.isDisabled) {
this.untoggle(checkbox);
}
}
}
findIndex(checkbox) {
return this.model.reduce(function(cur, val, index) {
if (val.name === checkbox.name && cur === -1) {
return index;
}
return cur;
}, -1);
}
addToModel(checkbox) {
this.model.push(checkbox);
}
removeFromModel(i) {
this.model.splice(i, 1);
}
toggle(checkbox) {
if (checkbox.isDisabled) {
return false;
}
let existingIndex = this.findIndex(checkbox);
if (existingIndex === -1) {
this.addToModel(checkbox);
}
else {
this.removeFromModel(existingIndex);
}
checkbox.isChecked = !checkbox.isChecked;
this.onModelChange.emit(this.model);
this.callback ? this.callback.emit() : false;
}
untoggle(checkbox) {
let existingIndex = this.findIndex(checkbox);
this.removeFromModel(existingIndex);
checkbox.isChecked = false;
this.onModelChange.emit(this.model);
}
}
这是由 ngDoCheck
中的 this.untoggle(checkbox)
中的 this.onModelChange.emit(this.model);
引起的。这是一个完美的无限循环。 this.onModelChange.emit(this.model);
导致更改检测,因此 ngDoCheck()
到 运行 并且循环再次开始。
确保更改检测不会导致更改检测。 ngDoCheck
由变更检测调用,不得调用另一个变更检测,否则会出现无限循环。
我觉得 Angular 2 缺少 Angular 1 所具有的一些东西,其中之一就是 $watch
函数。
OnChanges
和 DoCheck
应该替换 $watch
但我无法使用其中任何一个来获得所需的结果。 OnChanges
无法监听对象,因此在这种情况下没有用,虽然 DoCheck
完成了这项工作,但它会导致巨大的滞后,因为一旦发生变化它似乎就会变得疯狂。
这里我有一个组件,它有一堆复选框,每个复选框切换都会导致将一个值添加到数组,而不是默认的 true/false
功能。
在此组件中我需要注意的是复选框的 isDisabled
状态,因此每次更改时我都需要更新 checkbox
的 isChecked
状态。
就像我说的,它有效,但它在每个复选框切换时都有 2-3 秒的延迟,尽管只有 5 个复选框。最好我不希望每次切换复选框时循环到 运行,而是仅当复选框的 isDisabled
状态发生变化时才循环。
编辑:有人告诉我 Observable
可以在这里完成这项工作,但我找不到任何将其应用于对象数组的示例,例如这个。它还需要在不手动调用其 next()
方法的情况下触发,因为它必须侦听对正在发送的数组的外部更改。
编辑 2:我创建了一个不显示延迟的 plunkr,可能是因为在我的应用程序中我还有其他可能对延迟有影响的东西。但是,plunkr 清楚地表明似乎有问题,因为我在 ngDoCheck()
函数中放置了一个 console.log(true)
并且它 运行 是很多次。这不是有意的,如果是,那就太奇怪了。
这里是 plunkr:https://plnkr.co/edit/dJVnqbrredDyWTXNDzDK?p=preview
我该怎么做?
export class FormCheckboxMultipleComponent implements OnInit, DoCheck {
@Input() model: Array<any>;
@Output('modelChange') onModelChange: EventEmitter<any> = new EventEmitter();
@Output() callback: EventEmitter<any> = new EventEmitter();
constructor(private _globals: GlobalVariablesService) {
this.ns = _globals.ns;
}
ngOnInit() {
this.model = this.model || [];
}
ngDoCheck() {
for (let checkbox of this.checkboxes) {
if (checkbox.isDisabled) {
this.untoggle(checkbox);
}
}
}
findIndex(checkbox) {
return this.model.reduce(function(cur, val, index) {
if (val.name === checkbox.name && cur === -1) {
return index;
}
return cur;
}, -1);
}
addToModel(checkbox) {
this.model.push(checkbox);
}
removeFromModel(i) {
this.model.splice(i, 1);
}
toggle(checkbox) {
if (checkbox.isDisabled) {
return false;
}
let existingIndex = this.findIndex(checkbox);
if (existingIndex === -1) {
this.addToModel(checkbox);
}
else {
this.removeFromModel(existingIndex);
}
checkbox.isChecked = !checkbox.isChecked;
this.onModelChange.emit(this.model);
this.callback ? this.callback.emit() : false;
}
untoggle(checkbox) {
let existingIndex = this.findIndex(checkbox);
this.removeFromModel(existingIndex);
checkbox.isChecked = false;
this.onModelChange.emit(this.model);
}
}
这是由 ngDoCheck
中的 this.untoggle(checkbox)
中的 this.onModelChange.emit(this.model);
引起的。这是一个完美的无限循环。 this.onModelChange.emit(this.model);
导致更改检测,因此 ngDoCheck()
到 运行 并且循环再次开始。
确保更改检测不会导致更改检测。 ngDoCheck
由变更检测调用,不得调用另一个变更检测,否则会出现无限循环。