*ngFor:Parent 数组索引处的元素重置 Child 组件
*ngFor: Parent element at array index resets Child component
我有一个 Parent 组件,其数组为 Objects。
我使用 *ngFor 循环通过 @Input() 和每个索引处的元素填充 Child 组件。
如果我更改索引处的 object,child 组件将完全重置,而不是仅仅接受新的输入并保持它的其他属性。
Stackblitz minimal example
打字稿:
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
}
Parent 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>
Child HTML:
<div (click)="selected = !selected">
a: {{inputObject.a}}
b: {{inputObject.b}}
SELECTED: {{selected}}
</div>
结果
在 parent HTML 中,[inputObject]="objectArray[0]"
是我发现的唯一解决方案,它在更改 [=16] 中的元素时保持 Child 的其他属性=].
这对我来说不够好,因为我有很多 object 要显示。
有没有更好的方法可以在不完全重置组件的情况下将数据发送到组件中?
我曾尝试将 Angular Accessors
与 @Input() set inputObject {...}
一起使用,但无法维护组件的属性。也就是说,构造函数在 inputObject
更改时再次执行,将所有属性重置为默认值。
你需要通过一些索引来跟踪你的对象,在你执行你的 changeAnObject 操作后它不会改变。
<div *ngFor="let object of objectArray; let index = index; trackBy: trackByFn">
你的 trackByFn 是:
trackByFn(index, item) {
return item.a;
}
照着做就行了! :)
它所做的是通过唯一且不变的 id 跟踪对象,它不会通过 ngFor 循环重复,因为它检测到正在跟踪循环的 id 没有改变
我的示例基于您的 stackBlitz
我有一个 Parent 组件,其数组为 Objects。
我使用 *ngFor 循环通过 @Input() 和每个索引处的元素填充 Child 组件。
如果我更改索引处的 object,child 组件将完全重置,而不是仅仅接受新的输入并保持它的其他属性。
Stackblitz minimal example
打字稿:
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
}
Parent 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>
Child HTML:
<div (click)="selected = !selected">
a: {{inputObject.a}}
b: {{inputObject.b}}
SELECTED: {{selected}}
</div>
结果
在 parent HTML 中,[inputObject]="objectArray[0]"
是我发现的唯一解决方案,它在更改 [=16] 中的元素时保持 Child 的其他属性=].
这对我来说不够好,因为我有很多 object 要显示。
有没有更好的方法可以在不完全重置组件的情况下将数据发送到组件中?
我曾尝试将 Angular Accessors
与 @Input() set inputObject {...}
一起使用,但无法维护组件的属性。也就是说,构造函数在 inputObject
更改时再次执行,将所有属性重置为默认值。
你需要通过一些索引来跟踪你的对象,在你执行你的 changeAnObject 操作后它不会改变。
<div *ngFor="let object of objectArray; let index = index; trackBy: trackByFn">
你的 trackByFn 是:
trackByFn(index, item) {
return item.a;
}
照着做就行了! :)
它所做的是通过唯一且不变的 id 跟踪对象,它不会通过 ngFor 循环重复,因为它检测到正在跟踪循环的 id 没有改变
我的示例基于您的 stackBlitz