我有一个家长组件

@Component({
    selector: 'parent-component',
    templateUrl: 'parent-component.html',
})
export class ParentComponent {
    items : SomeClass[] = [....]; // Populated array

    onSomeEvent() {
        this.items[1] = new SomeClass(..);
    }
}

与模板

<tr *ngFor="let item of items">
  <child-component [item]="item"/>
</tr>

我有一个子组件

@Component({
    selector: 'child-component',
    templateUrl: 'child-component.html',
})
export class ChildComponent implements OnChanges {

    @Input() item! : SomeClass;

    constructor() {
        console.log('Child#constructor');
    }

    ngOnChanges(changes : SimpleChanges) : void {
        for (const propName in changes) {
            const change : SimpleChange = changes[propName];    
            console.log('Child#ngOnChanges prop="' + propName + '" change=' + change);
        }
    }
}

我在父组件中更改了数组的一个元素,子组件将被重新创建,而不是被通知输入的更改.

即调用ParentCompoenent #onSomeEvent()导致日志(log):

  Child#constructor
  Child#ngOnChanges prop="item" change={previousValue:undefined currentValue=SomeClass(..) firstChange=true}

为什么要重新创建ChildComponent,而不是仅仅调用ngOnChanges?

推荐答案

当我们没有在*ngFor上设置trackBy函数时,ngFor不知道哪个值发生了变化,因为数组中的每个元素都存储为引用(内存中的位置).

从ngFor的Angular 来看,不可能知道哪个元素被更改了,所以它会还原!

因此,通过使用trackBy,我们可以通知*ngFor一个原语可以用来标识哪个元素是哪个,好的值将是某个id字段,或者使用index

需要修改代码!

HTML

<tr *ngFor="let item of items;trackBy:trackByIndex">
  <child-component [item]="item"/>
</tr>

ts

trackBy = (i: number): number => {
  return i;
};

按值跟踪示例

trackByValue = (index: number, item: object): string => {
  return item.id;
};

Angular相关问答推荐

Angular material 输入字段中的图标未显示

如何从Angular TS文件传递$Events对象?

使Angular 效果只执行一次

访问Angular 模板中的HTML元素属性

material 对话框中没有合适的注塑

HTTP POST响应失败Angular 16

从canActivate创建时,Angular material 对话框不接收MAT_DIALOG_DATA

带独立零部件的TranslateLoader[Angular 16]

Angular 信号 - 使用 mutate() 与使用 forEach() react 性

TypeError:this.restoreDialogRef.afterClosed 不是函数

Angular 13 - 何时创建嵌入式视图?

当访问令牌在 MSAL for Angular 中过期时如何重定向用户?

如何在 Angular Cli 中生成 .angular-cli.json 文件?

如何在 Angular 4 中使用 Material Design 图标?

Angular 4 Bootstrap 下拉菜单需要 Popper.js

为什么用?模板绑定中的运算符?

Angular 2表单验证重复密码

在 Angular 2 中使用逗号作为列表分隔符

Angular 4 material表突出显示一行

Angular ngClass 和单击事件以切换类