当我将新项目推送到数组中时,未检测到角度输入属性更改

Dev*_*tel 1 javascript typescript angular-material angular angular-reactive-forms

我有一个数组(数据源)列表,我正在其中执行添加和删除操作。我在子组件中传递了一个数组(dataSource),并在子组件中添加了 *ngFor 循环。我已将数组作为 getter setter 传递以检测 @Input 更改。

这是我的AppComponent

<div>
    <vertital-tabs
          [config]="config"
          [dataSource]="dataSource"    <-- Array changes I want to detect in Child
          [(selectedItem)]="selectedItem">
    </vertital-tabs>

    <div style="background-color: yellow;margin: 10px">
        {{ selectedItem | json }}
     </div>
</div>
Run Code Online (Sandbox Code Playgroud)

ChildComponent (垂直制表符) 中:

get dataSource(): any {
    return this._dataSource;
}

@Input() set dataSource(value: any) {
    this._dataSource = value;
    // Not called this on Add New button even if Input Datasource is changed.
    // I want this to be called on Add New Item button click....
    debugger;
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我在数组上添加新项目时,它没有调用 setter @Input 更改方法。当我删除一个项目时,它工作正常并调用@Input Change。

注意:我有很多属性作为实际场景中的输入,所以我不想使用 ngOnChanges()

这是我创建的一个示例:https ://stackblitz.com/edit/angular-vertical-tabs-component-split-yzynef

小智 6

Angular 仅检查引用是否已更改 - 如果自上次检查以来未更改,则不会调用 setter。

app.component.ts

let nextItem = this.dataSource.length;
this.dataSource.push({
  id: nextItem.toString(),
  text: 'item ' + nextItem.toString(),
  icon: 'settings',
});
Run Code Online (Sandbox Code Playgroud)

在这里,您可以向数组中添加一些内容,而不是创建一个新数组并将其分配给dataSource.

vertical-tabs.ts

onDelete(item, index) {
  this.dataSource = this.dataSource.filter((x) => x !== item);
}
Run Code Online (Sandbox Code Playgroud)

在这里,您创建一个新数组并将其分配给dataSource

这就是为什么删除可以按预期工作,但添加却不能。复制数组并将其分配给dataSource应该可以解决您的问题:

let nextItem = this.dataSource.length;
this.dataSource = [
  ...dataSource,
  {
    id: nextItem.toString(),
    text: 'item ' + nextItem.toString(),
    icon: 'settings',
  }
];
Run Code Online (Sandbox Code Playgroud)