我正确使用FormArray吗?

时间:2017-05-24 12:16:16

标签: angular

所以我有没有错误编译的代码,但是在使用时我收到错误...

我的表单组件:

export class OrderHeaderComponent implements OnInit {
    orderForm: FormGroup;
    orderLines: FormArray;

    ngOnInit() {
        // build the form model
        this.orderLines = this.fb.array([])
        this.orderForm = this.fb.group({

            orderHeadForm: this.fb.group({ // create nested formgroup to pass to child
                selectTypeahead: ['', 
                                    Validators.required],
                ohReference: ['', 
                                    Validators.required],
                }),

            orderLines: this.orderLines,

        })

    }

    someFunction(){
        this.orderLines.push(this.fb.group({
                    ['newInputName']: ['', 
                                    Validators.required],
                    }));
    }
}

现在这是一个父组件,它将表单传递给各个子组件(这可以减去我目前正在处理的formArray部分)。每个孩子看起来像这样: parent_template:

<form [formGroup]="orderForm" (ngSubmit)="orderFormSubmit()">
    <childTemplate [orderHeadForm]="orderForm.controls.orderHeadForm">
    </childTemplatet>
</form>

儿童模板:

<div class="form-group" [formGroup]="orderHeadForm">
        <label for="oh-custaccount">Customer Account #</label>

    <input class="form-control" type="text" 
    formControlName="selectTypeahead"
    (focusout)=lookupCustomerAccountReactive() />

    <p *ngIf="orderHeadForm.controls.selectTypeahead.errors?.required" 
    style="color:red;">Number required!</p>
</div>

子组件:

export class CustomerSelect implements OnInit {

    @Input() orderHeadForm: FormGroup;

....
}

现在在这一点上,我甚至没有尝试从formArray渲染新的表单输入,我只是想让它们创建没有错误,所以我可以在之后构建模板。但是,当我调用someFunction()将新项添加到orderLines数组时,我的应用程序崩溃了:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '{
"orderHeadForm": {
    "selectTypeahead": "",
    "ohReference": ""
},
"orderLines": []
}'. Current value: '{
"orderHeadForm": {
    "selectTypeahead": "",
    "ohReference": ""
},
"orderLines": [
    {
    "newInputName": ""
    }
]
}'

现在我看到了这个帖子:

how to access the index value of formarray of angular, when nested formControls are placed in a separate component?

但是,如果我说30个子组件都需要这个,也许我在表单设置/构造上做错了。我做错了什么/使用表单数组不正确?由于没有提及文档中提到的修复,我怀疑我的用例是独一无二的。

1 个答案:

答案 0 :(得分:1)

由于某些原因,在运行函数someFunction时出现更改检测问题。您想知道是否需要根据您共享的链接在每个孩子中添加手动更改检测。但在这种情况下,这不是必要的。为什么呢?

重要的是,设置@Input时不会抛出错误。这工作正常,而不是抛出错误。当您在父级中调用函数someFunction时会发生错误,这表明变更检测的问题就在那时。

通过触发行后的手动更改检测:

this.orderLines.push(this.fb.group({
   ['newInputName']: ['', Validators.required],
}));
因此,

应该足够,并且不需要在每个孩子中触发变化检测。所以你的代码应该是这样的:

import {ChangeDetectorRef} from '@angular/core'

constructor(private ref: ChangeDetectorRef) { }

someFunction(){
  this.orderLines.push(this.fb.group({
     ['newInputName']: ['', Validators.required],
  }));
  this.ref.detectChanges();
}