我正确使用 FormArray 吗?

cro*_*sey 3 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],
                    }));
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<form [formGroup]="orderForm" (ngSubmit)="orderFormSubmit()">
    <childTemplate [orderHeadForm]="orderForm.controls.orderHeadForm">
    </childTemplatet>
</form>
Run Code Online (Sandbox Code Playgroud)

子模板:

<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>
Run Code Online (Sandbox Code Playgroud)

子组件:

export class CustomerSelect implements OnInit {

    @Input() orderHeadForm: FormGroup;

....
}
Run Code Online (Sandbox Code Playgroud)

现在,我什至不尝试从 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": ""
    }
]
}'
Run Code Online (Sandbox Code Playgroud)

现在我看到了这个线程:

当嵌套的 formControls 放置在单独的组件中时,如何访问 Angular 的 formarray 的索引值?

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

AJT*_*T82 5

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

原因是,设置 @Input 时不会引发错误。这工作正常并且不会抛出错误。当您在父级中调用该函数时会发生错误someFunction,这表明更改检测的问题就在此时。

通过在行后触发手动变化检测:

this.orderLines.push(this.fb.group({
   ['newInputName']: ['', Validators.required],
}));
Run Code Online (Sandbox Code Playgroud)

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

import {ChangeDetectorRef} from '@angular/core'

constructor(private ref: ChangeDetectorRef) { }

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