Angular。形式数组。找不到路径为:'jobs -> 0 -> name' 的控件

Angular. FormArray. Cannot find control with path: 'jobs -> 0 -> name'

我有一个在组件构造函数中初始化的表单:

constructor(
private fb: FormBuilder,
 ) {
    this.form = this.fb.group({
      practice: [''],
      jobs: this.fb.array([
        this.fb.group({
          name: ['', [Validators.required]],
          dateRange: [{startDate: null, endDate: null}, [Validators.required]],
        }),
      ]),
    });
  }

它的值是这样设置的:

@Input() set profile(newValue: Partial<FormModel>) {
  this.form.patchValue(newValue);

  if (value?.jobs.length) {
    this.form.setControl('jobs', this.fb.array(newValue.jobs));
  }
}

如果 newValue 在'jobs'中有多个元素,patchValue 只设置其中一个,因为只声明了一个元素在构造函数中。这就是为什么我还添加了 setControl,它似乎工作正常 - 当我输出 this.form.value 时,它的值与 新值。但是我在模板中显示它时遇到了麻烦。这就是我的 html 的样子:

<nz-form-control formArrayName="jobs">
  <ng-container
    *ngFor="let job of form.get('jobs').controls; let i=index"
    [formGroupName]="i"
  >
    <input formControlName="name"/>
    <app-range-datepicker
      formControlName="dateRange"
    ></app-range-datepicker>
  </ng-container>
</nz-form-control>

我在每个控件的控制台中都收到错误(如果有 2 个作业):

Cannot find control with path: 'jobs -> 0 -> name'

Cannot find control with path: 'jobs -> 0 -> dateRange'

Cannot find control with path: 'jobs -> 1 -> name'

Cannot find control with path: 'jobs -> 1 -> dateRange'

(at setUpControl, at FormGroupDirective.addControl)

FormArray 可能有点棘手...而且 Angular docs 没有明确告诉您它的元素特性。

每次 add/remove 项目时,您都需要在 form Formgroup 中构建 FormArray 元素,因为父级 formpatchValue 调用不知道怎么做。

通常的做法是为您创建一个构建 FormArray 的方法,这样可以添加项目:


addJob() {
  const formArray = <FormArray>this.form.get('jobs');
  formArray.push(
     this.fb.group({
          name: ['', [Validators.required]],
          dateRange: [{startDate: null, endDate: null}, [Validators.required]],
     })
   )
}

对于初始值,您需要从构造函数的初始值创建数组:

constructor(
private fb: FormBuilder,
 ) {
    this.form = this.fb.group({
      practice: [''],
      jobs: this.fb.array([]),
    });
    
    const formArray = <FormArray>this.form.get('jobs');
    this.initialValues.forEach(value => { // <-- might have to test if "this.initialValues" is null here, I am also assuming this is an array
       formArray.push(
          this.fb.group({
                 name: [value.name, [Validators.required]],
                 dateRange: [{startDate: value.startDate, endDate: value.endDate}, Validators.required]], // <- I am assuming the value shape here... but I think you got the gist of it
                 })
       );
    });
  }