使用 *ngFor 时如何避免 :enter/:leave 动画值变化?
How to avoid :enter/:leave animations on value change when using *ngFor?
我正在使用 angular 9 和 angular material。
我有我想要编辑的动态字符串列表 - 每个都在一个单独的输入中。
我也希望能够添加和删除它们,并为此添加一些动画。
问题: :enter 和 :leave 动画在每次值更改时触发。
Stackblitz:https://stackblitz.com/edit/angular-material-baseline2-7pmidv
到目前为止,我想到的最佳解决方案是使用单独的对象来存储值。
public list:{value:string}[] = [{value: "1"}, {value: "2"}, {value:"3"}];
而不是
public list: string[] = ["1", "2", "3"];
我想知道是否有更好的方法。
那是因为 ngFor
的内部运作方式。一旦被跟踪元素的引用发生变化 ngFor
将重新呈现它。
由于 javascript 不会在堆栈上保存对基元的引用,而是直接保存值,因此每次值更改都会更改堆栈上的值,因此 ngFor
将重新渲染您的对象。
因此,如果您将其包装在一个对象中并且仅更改对象值,则不会发生引用更改,这就是您的解决方案有效的原因。
但是为了防止这种情况,Angular 提供了 trackByFn。此函数允许您为对象定义唯一标识符,如果标识符保持不变,即使 reference/value 更改,您的对象也不会重新呈现。所以我认为你最好的选择是使用索引作为唯一标识符:
打字稿:
trackItem(index:number,item:string){
return index;
}
HTML:
<div [@inOutAnimation] *ngFor="let val of list; index as i;trackBy:trackItem" class="form-field">
<mat-form-field >
<mat-label>At</mat-label>
<input matInput [(ngModel)] = "list[i]">
</mat-form-field>
<button mat-icon-button class="add-shift-btn" (click)="removeShift(i)">
<mat-icon aria-hidden="false" aria-label="Example home icon">delete</mat-icon>
</button>
</div>
我正在使用 angular 9 和 angular material。 我有我想要编辑的动态字符串列表 - 每个都在一个单独的输入中。 我也希望能够添加和删除它们,并为此添加一些动画。
问题: :enter 和 :leave 动画在每次值更改时触发。
Stackblitz:https://stackblitz.com/edit/angular-material-baseline2-7pmidv
到目前为止,我想到的最佳解决方案是使用单独的对象来存储值。
public list:{value:string}[] = [{value: "1"}, {value: "2"}, {value:"3"}];
而不是
public list: string[] = ["1", "2", "3"];
我想知道是否有更好的方法。
那是因为 ngFor
的内部运作方式。一旦被跟踪元素的引用发生变化 ngFor
将重新呈现它。
由于 javascript 不会在堆栈上保存对基元的引用,而是直接保存值,因此每次值更改都会更改堆栈上的值,因此 ngFor
将重新渲染您的对象。
因此,如果您将其包装在一个对象中并且仅更改对象值,则不会发生引用更改,这就是您的解决方案有效的原因。
但是为了防止这种情况,Angular 提供了 trackByFn。此函数允许您为对象定义唯一标识符,如果标识符保持不变,即使 reference/value 更改,您的对象也不会重新呈现。所以我认为你最好的选择是使用索引作为唯一标识符:
打字稿:
trackItem(index:number,item:string){
return index;
}
HTML:
<div [@inOutAnimation] *ngFor="let val of list; index as i;trackBy:trackItem" class="form-field">
<mat-form-field >
<mat-label>At</mat-label>
<input matInput [(ngModel)] = "list[i]">
</mat-form-field>
<button mat-icon-button class="add-shift-btn" (click)="removeShift(i)">
<mat-icon aria-hidden="false" aria-label="Example home icon">delete</mat-icon>
</button>
</div>