ngOnChanges 仅在最后一次迭代时触发
ngOnChanges only triggered on last iteration
我有以下结构:
Data-Handling Component
|
|-- Grid Component
|-- Chart Component
即 Data-Handling
组件是两个同级组件的父级:Grid
和 Chart
。
我有一个数字数组,通过 @Input()
/ @Output
属性在三个组件之间共享。
当我在 Grid
组件中更新数组的单个值时,@Output()
属性 将信息发送到父 Data-Handling
组件,后者又,通过他的 @Input()
属性之一将信息发送到 Chart
组件。
因此(我重写并跳过了一些代码,因此可能存在一些语法错误):
grid.component.html:
[Not Relevant?]
grid.component.ts:
@Input() gridValues: any[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@Output() valueChanged: EventEmitter<any> = new EventEmitter<any>()
updateAllValuesToThree(): void {
for (var i = 0; i < this.gridValues.length; i++) {
this.updateValue(i, 3)
}
}
updateValue(index: number, value: number): void {
let updatedValue: any = {}
updatedValue.index = index
updatedValue.value = value
this.gridValues[index] = value
this.valueChanged.emit(updatedValue)
}
dataHandling.component.html:
<grid (valueChanged)="onValueUpdate($event)"
[gridValues]="dataArray">
</grid>
<chart [chartData]="dataArray"
[individualValueChanged]="individualValueChanged">
</chart>
dataHandling.component.ts:
dataArray: number[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
individualValueChanged: any = {}
onValueUpdate(event: any): void {
this.dataArray[event.currentValue.index] = event.currentValue.value
this.individualValueChanged = event.currentValue
}
chart.component.ts:
@Input chartData: number[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@Input individualValueChanged: any = {}
ngOnChanges(changes: SimpleChanges): void {
if (changes.individualValueChanged && changes.individualValueChanged.currentValue) {
let changeInfo: any = changes.individualValueChanged.currentValue
this.chartData[changeInfo.index] = changeInfo.value
}
}
chart.component.html:
[Not Relevant?]
嗯。如果我将 SINGLE 值从 Grid
更新为 Chart
,一切正常。
但是,当我在 for
循环中为 gridValues
数组的每个元素调用 EventEmitter
时, 仅修改了数组的最后一个元素在 chart
组件的 chartData
数组中 .
所以:
- 在
Grid
组件中我有:[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
- 在
Data-Handling
组件中我有:[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
- 在
Chart
组件中我有:[1, 2, 3, 4, 5, 6, 7, 8, 9, 3]
每个事件都会从 Grid
正确触发到 Data-Handling
组件,但只有最后一个更新事件进入 Chart
组件,从而触发 ngOnChanges()
。
这是否按预期工作?我错过了什么吗?
这是预期的行为。 @Input
更新是在更改检测期间完成的。 @Output
在更改检测之外进行处理。
当您在此处触发事件时:
for (var i = 0; i < this.gridValues.length; i++) {
this.updateValue(i, 3)
}
触发了数据处理组件中的以下方法:
onValueUpdate(event: any): void {
this.dataArray[event.currentValue.index] = event.currentValue.value
this.individualValueChanged = event.currentValue
}
所以你触发多少次这个方法就触发多少次this.updateValue(i, 3)
。 event.currentValue
的最后一个值将设置为 this.individualValueChanged
。
只有在处理完所有事件后,Angular 才会进入变更检测阶段并更新包含最后一个值的输入 individualValueChanged
绑定。
有关更改检测的更多信息,请阅读 Everything you need to know about change detection in Angular. Also read Two Phases of Angular Applications
我有以下结构:
Data-Handling Component
|
|-- Grid Component
|-- Chart Component
即 Data-Handling
组件是两个同级组件的父级:Grid
和 Chart
。
我有一个数字数组,通过 @Input()
/ @Output
属性在三个组件之间共享。
当我在 Grid
组件中更新数组的单个值时,@Output()
属性 将信息发送到父 Data-Handling
组件,后者又,通过他的 @Input()
属性之一将信息发送到 Chart
组件。
因此(我重写并跳过了一些代码,因此可能存在一些语法错误):
grid.component.html:
[Not Relevant?]
grid.component.ts:
@Input() gridValues: any[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@Output() valueChanged: EventEmitter<any> = new EventEmitter<any>()
updateAllValuesToThree(): void {
for (var i = 0; i < this.gridValues.length; i++) {
this.updateValue(i, 3)
}
}
updateValue(index: number, value: number): void {
let updatedValue: any = {}
updatedValue.index = index
updatedValue.value = value
this.gridValues[index] = value
this.valueChanged.emit(updatedValue)
}
dataHandling.component.html:
<grid (valueChanged)="onValueUpdate($event)"
[gridValues]="dataArray">
</grid>
<chart [chartData]="dataArray"
[individualValueChanged]="individualValueChanged">
</chart>
dataHandling.component.ts:
dataArray: number[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
individualValueChanged: any = {}
onValueUpdate(event: any): void {
this.dataArray[event.currentValue.index] = event.currentValue.value
this.individualValueChanged = event.currentValue
}
chart.component.ts:
@Input chartData: number[] = [] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@Input individualValueChanged: any = {}
ngOnChanges(changes: SimpleChanges): void {
if (changes.individualValueChanged && changes.individualValueChanged.currentValue) {
let changeInfo: any = changes.individualValueChanged.currentValue
this.chartData[changeInfo.index] = changeInfo.value
}
}
chart.component.html:
[Not Relevant?]
嗯。如果我将 SINGLE 值从 Grid
更新为 Chart
,一切正常。
但是,当我在 for
循环中为 gridValues
数组的每个元素调用 EventEmitter
时, 仅修改了数组的最后一个元素在 chart
组件的 chartData
数组中 .
所以:
- 在
Grid
组件中我有:[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
- 在
Data-Handling
组件中我有:[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
- 在
Chart
组件中我有:[1, 2, 3, 4, 5, 6, 7, 8, 9, 3]
每个事件都会从 Grid
正确触发到 Data-Handling
组件,但只有最后一个更新事件进入 Chart
组件,从而触发 ngOnChanges()
。
这是否按预期工作?我错过了什么吗?
这是预期的行为。 @Input
更新是在更改检测期间完成的。 @Output
在更改检测之外进行处理。
当您在此处触发事件时:
for (var i = 0; i < this.gridValues.length; i++) {
this.updateValue(i, 3)
}
触发了数据处理组件中的以下方法:
onValueUpdate(event: any): void {
this.dataArray[event.currentValue.index] = event.currentValue.value
this.individualValueChanged = event.currentValue
}
所以你触发多少次这个方法就触发多少次this.updateValue(i, 3)
。 event.currentValue
的最后一个值将设置为 this.individualValueChanged
。
只有在处理完所有事件后,Angular 才会进入变更检测阶段并更新包含最后一个值的输入 individualValueChanged
绑定。
有关更改检测的更多信息,请阅读 Everything you need to know about change detection in Angular. Also read Two Phases of Angular Applications