Angular 2 - 具有可编辑输入的ngFor对象数组的双向绑定

时间:2017-09-12 16:51:14

标签: angular angular2-forms

我是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实现相同的想法,但它也没有成功。

2 个答案:

答案 0 :(得分:4)

我创建了一个Plunker。我删除了formControlName,因为它不是FormsModule,它是ReactiveFormsModule - 这是不同的。

有关FormsModule(NgModel)ReactiveFormsModule阅读文档之间的详细信息,请参阅。此外,最好删除,因为您使用的[(ngModel)]正在对该值进行双向数据绑定。

  <input
                        id="locations-{{index}}"
                        [(ngModel)]="business?.locations[index].country"
                        name="locations-{{index}}"
                        type="text" 
                        class="form-control"
                        placeholder="Country" 
                        aria-label="Country"
                        >

答案 1 :(得分:0)

(回答因为我还没有被允许发表评论)。除了@ alexKhymenko的答案之外,如果你想坚持使用ReactiveForms(模块),你必须将你在组件中创建的父formGroupbusinessForm添加到模板中。不确定这是否会解决您的问题,但请尝试将此属性添加到模板的<div class="form-group">顶部<div class="form-group" [formGroup]="businessForm">。如果你对非反应形式感到满意,那么@ alexKhymenko的回答可能就足够了。