我正在尝试创建一个表单,您可以在发送之前添加多行。为此,我正在使用行数组存储数据,并使用ngFor和ngModel将数据绑定/检索到我的表单中。
这是我的代码看起来像
export class MyComponent implements OnInit {
lines : Line[] = [];
constructor() { }
ngOnInit() {
this.lines.push(new Line("XXXXXX1",0,0));
}
addLine(){
let line = (new Line("XXXXXX1",0,0));
this.lines.push(line);
}
save(){
console.log(this.lines);
}
}
class Line {
type: string;
qteRejet : number;
qteComm : number;
constructor(type: string = "XXXX1", qteRej: number = 0, qteComm : number = 0){
this.type = type;
this.qteRejet = qteRej;
this.qteComm = qteComm;
}
}
和表格:
<div class="form-group">
<div class="row" *ngFor="let line of lines; let ind=index;">
<div class="col-lg-1">
<i class="fa fa-2x fa-plus-square add-btn" (click)="addLine()" *ngIf="lines[lines.length-1] === line"></i>
</div>
<div class="col-lg-3">
<select class="form-control" name="type" [(ngModel)]="lines[ind].type">
<option>XXXXXX1</option>
<option>XXXXXX2</option>
<option>XXXXXX3</option>
</select>
</div>
<div class="col-lg-4">
<input class="form-control" type="number" min="0" name="qteCommande" [(ngModel)]="lines[ind].qteComm">
</div>
<div class="col-lg-4">
<input class="form-control" type="number" min="0" name="qteRejet" [(ngModel)]="lines[ind].qteRejet">
</div>
</div>
</div>
当我一次添加所有行时,表单完美无缺。现在当我尝试填充一行然后添加另一行时,由于某种原因,表单会重置先前输入的行。
但是当我检查我的数组时,它仍然有输入的值
有人可以解释这里发生了什么/我做错了什么?任何帮助将不胜感激。
编辑:我尝试按照 @Ploppy 的建议使用trackBy并在我的行中添加了一个ID。我还将此行添加到表单中:
<p>{{line.id}} | {{line.type}} | {{line.qteComm}} | {{line.qteRejet}}</p>
表单重置但值正确绑定。
答案 0 :(得分:2)
问题是Angular会重新创建DOM,因为它无法识别这些行。为了帮助他,你需要使用* ngFor指令的trackBy方法,并通过一个唯一的属性来识别项目。
*ngFor="let line of lines; let ind=index; trackBy:trackByFn"
在您的组件中:
trackByFn(index,item){
return item.myCustomIndex; // myCustomIndex should be unique
}
默认情况下,trackBy方法从其数组中返回项目的索引。
答案 1 :(得分:2)
所以我终于找到了代码中的问题。我的输入位于form
内,添加新行添加了相同name
的输入(Agular 2中不允许)。用name
替换name=attribute-{{id}}
属性解决了这个问题。
<div class="form-group">
<div class="row" *ngFor="let line of lines; let ind=index;">
<div class="col-lg-1">
<i class="fa fa-2x fa-plus-square add-btn" (click)="addLine()" *ngIf="lines[lines.length-1] === line"></i>
</div>
<div class="col-lg-3">
<select class="form-control" name="type-{{ind}}" [(ngModel)]="lines[ind].type">
<option>XXXXXX1</option>
<option>XXXXXX2</option>
<option>XXXXXX3</option>
</select>
</div>
<div class="col-lg-4">
<input class="form-control" type="number" min="0" name="qteCommande-{{ind}}" [(ngModel)]="lines[ind].qteComm">
</div>
<div class="col-lg-4">
<input class="form-control" type="number" min="0" name="qteRejet-{{ind}}" [(ngModel)]="lines[ind].qteRejet">
</div>
</div>
</div>
这是一个总结所有内容的Plunker: Plunker