[英]Angular 2 - two way binding for ngFor objects array with editable inputs
I'm new to Angular 2, trying to implement ngFor list of objects with editable inputs, be able to add a new object and save the data. 我是Angular 2的新手,尝试实现ngFor具有可编辑输入的对象列表,能够添加新对象并保存数据。 The data is:
数据为:
business: { email: "email@something.com",
locations: [
{ country: "US", city: "city 1", address_line_1: "address 1"},
{ country: "Australia", city: "city 1", address_line_1: "address 2"}
]}
In the component: 在组件中:
ngOnInit() {
this.businessForm = new FormGroup({
email: new FormControl(null, [Validators.required]),
locationCountry: new FormControl(null)
});
addLocation() {
this.isFormChanged = true;
let newLocation = {};
this.business.locations.push(newLocation);
}
removeLocation(item){
if (null !== item) {
this.isFormChanged = true;
this.business.locations.splice(item, 1);
}
}
Html: HTML:
<div class="form-group">
<label for="locations">Locations</label>
<div class="row">
<div class="col-md-3">
<button
id="locations"
class="btn btn-secondary"
type="button"
(click)="addLocation()">Add new address</button>
</div>
</div>
<!--LOCATIONS LIST-->
<ul class="locations-tag">
<li *ngFor="let location of business?.locations; let index=index;">
<a class="btn btn-danger categories-tag-btn" (click)="removeLocation(index)">X</a>
<span>{{business?.locations[index].country}}</span>
<input
id="locations-{{index}}"
[(ngModel)]="business?.locations[index].country"
formControlName="locationCountry"
name="locations-{{index}}"
type="text"
class="form-control"
placeholder="Country"
aria-label="Country"
value={{business?.locations[index].country}}>
...
</li>
</ul>
</div>
When it runs I get an error 它运行时出现错误
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'US'. Current value: 'Australia'.
Looks like it changes all the inputs values to the last one. 看起来它将所有输入值更改为最后一个。 I tried to implement the same idea through FormBuilder, but it didn't work out either.
我试图通过FormBuilder实现相同的想法,但也没有奏效。
I have created a Plunker . 我创建了一个Plunker 。 I remove formControlName because it's not FormsModule, it's ReactiveFormsModule - that is different.
我删除formControlName,因为它不是FormsModule,而是ReactiveFormsModule-有所不同。
For more information between FormsModule(NgModel) vs ReactiveFormsModule read documentation. 有关FormsModule(NgModel)与ReactiveFormsModule之间的更多信息, 请阅读文档。 Also, it's better to delete value because you are using
[(ngModel)]
that is making two-way data-binding to the value. 另外,最好删除值,因为您正在使用
[(ngModel)]
对值进行双向数据绑定。
<input
id="locations-{{index}}"
[(ngModel)]="business?.locations[index].country"
name="locations-{{index}}"
type="text"
class="form-control"
placeholder="Country"
aria-label="Country"
>
(Answering since I am not yet allowed to comment). (正在回答,因为我尚未发表评论)。 In addition to @alexKhymenko's answer, if you want to stick with ReactiveForms(Module), you will have to add the parent
formGroup
, businessForm
you created in your component, also to the template. 除了@alexKhymenko的答案外,如果您想坚持使用ReactiveForms(Module),还必须将在组件中创建的父
formGroup
和businessForm
都添加到模板中。 Not sure if this will fix your issue though, but try to add this attribute to the top <div class="form-group">
like this <div class="form-group" [formGroup]="businessForm">
of the template. 不知道这是否能解决您的问题,但是请尝试将此属性添加到顶部的
<div class="form-group">
这样的<div class="form-group" [formGroup]="businessForm">
模板。 If you are happy with non-reactive forms, then @alexKhymenko's answer might be sufficient. 如果您对非反应性表单感到满意,那么@alexKhymenko的答案可能就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.