首页 > 解决方案 > *ngFor:数组索引处的父元素重置子组件

问题描述

我有一个带有对象数组的父组件。

我使用 *ngFor 循环通过 @Input() 使用每个索引处的元素填充子组件。

如果我更改索引处的对象,子组件会完全重置,而不是仅仅接受新的 Input 并维护它的其他属性。

Stackblitz 最小示例

打字稿:

export interface MyObject {
  a: string;
  b: string;
}

export class Parent {
  objectArray: MyObject[] = [
    {a: 'string A', b: 'string B'}
  ];

  changeAnObject() {
    const sameObject: MyObject = {a: 'string A', b: 'string B'};
    this.objectArray[0] = sameObject;
  }
}

export class Child {
  @Input() inputObject: MyObject;
  selected = false; // Some other property to maintain
}

父 HTML:

// 3 different ways to populate inputObject

<div *ngFor="let object of objectArray">
  <app-child [inputObject]="object"></app-child> // does not maintain "selected" property
</div>

<div *ngFor="let object of objectArray; let index = index">
  <app-child [inputObject]="objectArray[index]"></app-child> // does not maintain "selected" property
</div>

<div>
  <app-child [inputObject]="objectArray[0]"></app-child> // DOES maintain "selected" property
</div>

<button (click)="changeAnObject()">Change Object</button>

子 HTML:

<div (click)="selected = !selected">
    a: {{inputObject.a}}
    b: {{inputObject.b}}
    SELECTED: {{selected}}
</div>

结果

在父 HTML 中,[inputObject]="objectArray[0]"是我发现的唯一解决方案,它在更改objectArray[0].

这对我来说还不够好,因为我有很多对象要显示。

有没有更好的方法将数据发送到组件而不完全重置它们?我曾尝试使用Angular Accessorswith@Input() set inputObject {...}但它无法维护组件的属性。也就是说,构造函数在inputObject更改时再次执行,将所有属性重置为默认值。

标签: javascriptarraysangulartypescriptngfor

解决方案


您需要通过某个索引来跟踪您的对象,执行 changeAnObject 操作后该索引不会改变。

<div *ngFor="let object of objectArray; let index = index; trackBy: trackByFn">

你的 trackByFn 是:

trackByFn(index, item) {
   return item.a; 
}

就这样做吧,它会起作用的!:)

它的作用是通过唯一且不变的 id 跟踪对象,它不会通过 ngFor 循环重复,因为它检测到跟踪循环的 id 没有更改

我的示例基于您的 stackBlitz


推荐阅读