* ngFor: родительский элемент в индексе массива сбрасывает дочерний компонент - PullRequest
1 голос
/ 04 апреля 2020

У меня есть родительский компонент с массивом объектов.

Я использую * ngFor l oop для заполнения дочерних компонентов через @Input () с элементом в каждом индексе.

Если я изменяю объект по индексу, дочерний компонент полностью сбрасывается, вместо того, чтобы просто принять новый ввод и сохранить его другие свойства.

Пример минимального использования Stackblitz

TypeScript:

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]" - единственное найденное мной решение, которое поддерживает другие свойства Child при изменении элемента в objectArray[0].

Это недостаточно для меня, так как у меня есть много объектов для отображения .

Есть ли лучший способ отправить данные в Компоненты без их полной перезагрузки? Я попытался использовать Angular Accessors с @Input() set inputObject {...}, но это не помогло сохранить свойства компонента. То есть конструктор снова выполняется при изменении inputObject, возвращая все свойства к значениям по умолчанию.

1 Ответ

2 голосов
/ 04 апреля 2020

Вам нужно отслеживать по вашему объекту по некоторому индексу, который не изменится после выполнения вашего действия changeAnObject.

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

с вашим trackByFn:

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

Просто сделайте это так и будет работать! :)

Что он делает, так это, отслеживая объект по уникальному и неизменяющемуся идентификатору, он не будет повторяться через ngFor l oop, потому что он обнаружил, что идентификатор, отслеживающий l oop не был изменен

Мой пример был основан на вашем стеке Blitz

...