我正在制作动态表格。一个Field有值的列表。每个值由一个字符串表示。
Field
export class Field{ name: string; values: string[] = []; fieldType: string; constructor(fieldType: string) {this.fieldType = fieldType;} }
我的组件中有一个函数,可以向该字段添加新值。
addValue(field){ field.values.push(""); }
值和按钮在我的HTML中这样显示。
<div id="dropdown-values" *ngFor="let value of field.values; let j=index"> <input type="text" class="form-control" [(ngModel)]="field.values[j]" [name]="'value' + j + '.' + i"/><br/> </div> <div class="text-center"> <a href="javascript:void(0);" (click)="addValue(field)"><i class="fa fa-plus-circle" aria-hidden="true"></i></a> </div>
一旦我在值的输入中写入一些文本,输入就会失去焦点。如果我在一个字段中添加了多个值,并且在一个输入值中写入了一个字符,则该输入将失去焦点,并且该字符将写入每个输入中。
当数组是原始类型(在您的情况下是String数组)时,会发生这种情况。这可以通过使用解决TrackBy。因此,更改模板以匹配以下内容:
String
TrackBy
<div *ngFor="let value of field.values; let i=index; trackBy:trackByFn"> <input type="text" [(ngModel)]="field.values[i]" /><br/> </div> <div> <button (click)="addValue(field)">Click</button> </div>
并在ts文件中添加函数trackByFn,该函数返回值的(唯一)index值:
trackByFn
index
trackByFn(index: any, item: any) { return index; }
这是关于同一问题的 链接 ,除了该问题是针对AngularJS的,但该问题与您的情况相同。该页面最重要的摘录:
您正在数组上重复,并更改了数组的项目(请注意,您的项目是字符串,它们是JS中的基元,因此“按值”进行比较)。由于检测到新项目,因此从DOM中删除了旧元素,并创建了新元素(显然,它们没有得到关注)。
使用TrackByAngular可以根据唯一标识符跟踪已添加(或删除)了哪些项目,并仅创建或销毁了已更改的内容,这意味着您不会失去对输入字段的关注:)
如链接所示,您还可以修改数组以包含唯一的对象[(ngModel)]="value.id"(例如,使用),但这也许不是您所需要的。
[(ngModel)]="value.id"