Angular 2 - 具有可编辑输入的 ngFor 对象数组的双向绑定
Angular 2 - two way binding for ngFor objects array with editable inputs
我是 Angular 2 的新手,正在尝试实现具有可编辑输入的 ngFor 对象列表,能够添加新对象并保存数据。
数据为:
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"}
]}
在组件中:
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:
<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>
运行时出现错误
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'US'. Current value: 'Australia'.
看起来它将所有输入值更改为最后一个。
我试图通过 FormBuilder 实现同样的想法,但也没有成功。
我创建了一个 Plunker。我删除了 formControlName,因为它不是 FormsModule,它是 ReactiveFormsModule - 这是不同的。
有关 FormsModule(NgModel) vs ReactiveFormsModule 之间的更多信息,请阅读文档。此外,最好删除 value,因为您使用的 [(ngModel)]
正在对值进行双向数据绑定。
<input
id="locations-{{index}}"
[(ngModel)]="business?.locations[index].country"
name="locations-{{index}}"
type="text"
class="form-control"
placeholder="Country"
aria-label="Country"
>
(回答因为我还没有被允许发表评论)。除了@alexKhymenko 的回答之外,如果您想坚持使用 ReactiveForms(Module),则必须将您在组件中创建的父级 formGroup
、businessForm
添加到模板中。虽然不确定这是否会解决您的问题,但请尝试将此属性添加到模板的顶部 <div class="form-group">
,例如 <div class="form-group" [formGroup]="businessForm">
。如果您对非反应式表单感到满意,那么@alexKhymenko 的回答可能就足够了。
我是 Angular 2 的新手,正在尝试实现具有可编辑输入的 ngFor 对象列表,能够添加新对象并保存数据。 数据为:
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"}
]}
在组件中:
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:
<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>
运行时出现错误
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'US'. Current value: 'Australia'.
看起来它将所有输入值更改为最后一个。 我试图通过 FormBuilder 实现同样的想法,但也没有成功。
我创建了一个 Plunker。我删除了 formControlName,因为它不是 FormsModule,它是 ReactiveFormsModule - 这是不同的。
有关 FormsModule(NgModel) vs ReactiveFormsModule 之间的更多信息,请阅读文档。此外,最好删除 value,因为您使用的 [(ngModel)]
正在对值进行双向数据绑定。
<input
id="locations-{{index}}"
[(ngModel)]="business?.locations[index].country"
name="locations-{{index}}"
type="text"
class="form-control"
placeholder="Country"
aria-label="Country"
>
(回答因为我还没有被允许发表评论)。除了@alexKhymenko 的回答之外,如果您想坚持使用 ReactiveForms(Module),则必须将您在组件中创建的父级 formGroup
、businessForm
添加到模板中。虽然不确定这是否会解决您的问题,但请尝试将此属性添加到模板的顶部 <div class="form-group">
,例如 <div class="form-group" [formGroup]="businessForm">
。如果您对非反应式表单感到满意,那么@alexKhymenko 的回答可能就足够了。