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

时间:2017-09-18 15:02:04

标签: arrays angular typescript angular2-changedetection

我有以下结构:

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

那是Data-Handling组件是两个兄弟组件的父级:GridChart

我有一组数字,通过@Input() / @Output属性在三个组件之间共享。

当在Grid组件中更新数组的单个值时,@Output()属性会将信息发送到父Data-Handling组件,后者又将信息发送给Chart@Input()组件通过他的[Not Relevant?] 个属性。

因此(我重写并跳过了一些代码,因此可能会出现一些语法错误):

grid.component.html:

@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)
}

grid.component.ts:

<grid (valueChanged)="onValueUpdate($event)"
      [gridValues]="dataArray">
</grid>

<chart [chartData]="dataArray"
       [individualValueChanged]="individualValueChanged">
</chart>

dataHandling.component.html:

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
}

dataHandling.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.ts:

[Not Relevant?]

chart.component.html:

Grid

好。如果我将 SINGLE 值从Chart更新为EventEmitter,则一切正常。

但是,当我为for数组的每个元素调用gridValues循环内的chart时,只会在{{}中修改数组的最后一个元素1}}组件的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]

每个事件都会从Data-Handling正确触发Grid组件,但只有最后一次更新事件会进入Chart组件,从而触发ngOnChanges()

这是否按预期工作?我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

这是预期的行为。在更改检测期间完成@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。另请阅读Two Phases of Angular Applications