这是我的班级:
interface IHobby {
name: string;
type: string;
}
class User {
constructor(public name: string, public hobbies: IHobby[]) { }
}
现在我试图在Angular 4中做一个模板表格。我注意到为了显示爱好,我需要遍历它们。所以,这是我的HTML:
<div *ngFor="let h of user.hobbies; let i = index">
#{{i}}<br />
<input [(ngModel)]="h.name" name="hobby_name[{{i}}]" /> <br /><br />
<input [(ngModel)]="h.type" name="type[{{i}}]" />
<br /><br />
<button class="btn btn-warn" (click)="remove(i)">Remove</button>
<br /><br />
</div>
虽然这有效,但我不确定是否:
我正在以正确的Angular 4方式执行此操作 - 我应该对数组中的每个项目使用ngModel
吗?
将名称定义为name="hobby_name[{{i}}]"
是否可以?因为name="hobby_name_{{i}}"
也可以。什么是正确的HTML5和Angular 4方式?
这是一个工作样本:https://plnkr.co/edit/chOsfhBThD3dA9FFqNPX?p=preview
答案 0 :(得分:0)
您实际上不需要使用name属性,因为您将输入直接绑定到模型。如果要查看模型中的即时更改,可以继续使用[(ngModel)],但如果要在表单提交时更新模型,则不应使用ngModel。我会像这样做一个反应性的形式:
<div [formGroup]="form">
<div formArrayName="hobbiesFormArray">
<div *ngFor="let h of user.hobbies; let i = index" [formGroupName]="i">
#{{i}}<br />
<input formControlName="name" /> <br /><br />
<input formControlName="type" />
<br /><br />
<button class="btn btn-warn" (click)="remove(i)">Remove</button>
<br /><br />
</div>
</div>
</div>
然后在你的组件中我会做类似的事情:
form: FormGroup;
constructor(fb: FormBuilder) {
this.form = this.fb.group({
name: '',
hobbies: this.fb.array([])
});
}
ngOnChanges() {
this.form.reset({
name: this.user.name
});
this.setHobbies(this.user.hobbies);
}
get hobbiesFormArray(): FormArray {
return this.form.get('hobbiesFormArray') as FormArray;
};
setHobbies(hobbies: IHobby[]) {
const hobbiesFormArray = this.fb.array(hobbies.map(hobby => this.fb.group(hobby)));
this.form.setControl('hobbiesFormArray', this.fb.array());
}
然后在你的onSubmit方法中,我将表单模型转换回用户对象:
const formModel = this.form.value;
const newHobbies: IHobby[] = formModel.hobbiesFormArray
.map(() => (hobby: IHobby) => Object.assign({}, hobby))
const newUser: User = {
name: formModel.name as string,
hobbies: newHobbies
};
使用您拥有的任何方式保存newUser对象。