ngOnChanges 仅在最后一次迭代时触发

ngOnChanges only triggered on last iteration

我有以下结构:

Data-Handling Component
  |
  |-- Grid Component
  |-- Chart Component

Data-Handling 组件是两个同级组件的父级:GridChart

我有一个数字数组,通过 @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 正确触发到 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