【问题标题】:Getting "TypeError: Cannot read property 'controls' of undefined" While Using formArray in Recative forms在反应式表单中使用 formArray 时出现“TypeError:无法读取未定义的属性‘控件’”
【发布时间】:2019-09-13 07:53:22
【问题描述】:

我正在使用 formArray 创建动态表单。但我遇到了 “TypeError:无法读取未定义的属性'控件'”

enter code here
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
 export class AppComponent implements OnInit {
 title = 'Trainner Registration Form ';
 registrationForm: FormGroup;

 get LanguagesForm() {
    return this.registrationForm.get('Languages') as FormArray;
 }

 addLanguage() {
  this.LanguagesForm.push(this.fb.control(''));
}


 constructor(private  fb : FormBuilder ) {}
   ngOnInit(){
     this.registrationForm = this.fb.group({
      personalDetails : this.fb.group({
      name: this.fb.group({
        firstName: [''],
        lastName: ['']
      }),
      aboutYours: [''],
      dob: [''],
      // lang: [''],
      Languages: this.fb.array([]),
      wTT: ['']
    })
  });

}


onSubmit() {
  console.log(this.registrationForm.value);
  // this._registerationservice.register(this.registrationForm.value).subscribe(
  //   response => console.log('Success', response),
  //   error => console.log('Error',error)
  // );
}

}

预期结果:如果用户单击“添加语言”按钮,应创建一个新的输入字段。

实际结果:我收到“TypeError: Cannot read property 'controls' of undefined”

app.component.html 文件

<div style="text-align:center">
<h1>Welcome to {{ title }}!</h1>
</div>

<mat-horizontal-stepper >

  <mat-step  [stepControl]="personalDetails">
    <ng-template matStepLabel>Enter Personal Details</ng-template>
    <div formGroupName="personalDetails">
      <div formGroupName="name">
          <div class="form-group">
            <label>First Name : </label>
            <input type="text"  formControlName="firstName" class="form-control"  >
          </div>

          <div class="form-group">
            <label>Last Name : </label>
            <input type="text" formControlName="lastName" class="form-control">
          </div>
      </div>    
      <div class="form-group">
          <label>DOB : </label>
          <input type="date" formControlName="dob" class="form-control">
        </div>

        <div class="form-group">
          <label>About Yourself : </label>
          <textarea formControlName="aboutYours" class="form-control"></textarea>
        </div>

        <div class="form-group">
            <label>Language(s) : </label>
            <button type="button" class="btn btn-secondary btn-sm m-2" (click)="addLanguage()">Add Language</button>
            <!-- <input type="text" formControlName="lang" class="form-control"> -->

            <div formArrayName="Languages">
                <div *ngFor="let lang of langsform.controls; let i =index;">
                    <input type="text" class="form-control" [formControlName]="i">
                </div>
              </div>

          </div>


</mat-horizontal-stepper>
</form>
</div>

【问题讨论】:

  • 你能提供 addLanguage() 函数让我们看看里面是什么吗? @GRV
  • check mu 回答你需要从表单数组中设置上父级????
  • 使用 getter 并获取 ts 文件中的控件。您的 IDE 将为您提供帮助,您将知道您的代码是 typescript 安全的
  • @HarisHajdarevic 请检查更新的代码。谢谢
  • @GRV 你检查我的答案了吗??

标签: javascript angular typescript


【解决方案1】:

发生这种情况是因为您没有将personalDetails 的上层formGroup 设置为registrationForm 中名称为Languages 的控件,其中LanguagespersonalDetails 形式中的控件组,还有一个与LanguagesForm.controls 相关的错字必须是“Languages.controls”

<div class="form-group">
  <label>Language(s) : </label>
  <button type="button" class="btn btn-secondary btn-sm m-2" (click)="addLanguage()">Add Language</button>

  <div [formGroup]="registrationForm"> <!-- ? -->
    <div [formGroupName]="'personalDetails'"> <!-- ? -->

      <div formArrayName="Languages">
        <div *ngFor="let lag of registrationForm.get('personalDetails').get('Languages').controls; let i =index;">
          <input type="text" class="form-control" [formControlName]="i">
        </div>

      </div>
    </div>
  </div>
</div>

您可以使用 get 属性来访问这样的语言表单

  langsform() :FormArray { 
    return this.registrationForm.get('personalDetails').get('Languages') as FormArray 
  }

模板

<div [formGroup]="registrationForm">
  <div [formGroupName]="'personalDetails'">

    <div formArrayName="Languages">
      <div *ngFor="let lang of langsform.controls; let i =index;">
          <input type="text" class="form-control" [formControlName]="i">
      </div>
    </div>
  </div>
</div>

demo ??

【讨论】:

【解决方案2】:

我认为问题在于你在 onInit 中初始化了 registrationForm 对象,此时模板已经被解析,所以你应该在这个 div 上添加一个*ngIf="this.registrationForm" &lt;div formArrayName="Languages"&gt;

【讨论】:

【解决方案3】:

试试这个方法:

在您的 HTML 中:

 <div class="form-group">
      <div formArrayName="languages">
        <label>Languages</label>

        <div class="row">
          <div class="col-8">
            <input type="text" class="form-control" id="languages">
          </div>
          <div class="col-4">
            <button type="button" class="btn btn-primary" (click)="onAddLanguages()">Add</button>
          </div>
        </div>

        <div class="form-group row" *ngFor="let languages of registrationForm.get('languages').controls; let i = index">
          <div class="col-8">
            <input type="text" class="form-control" [formControlName]="i">
          </div>
          <div class="col-4">
            <button type="button" class="btn btn-danger" (click)="onDeleteLanguages(i)">Delete</button>
          </div>
        </div>
      </div>
    </div>

在您的 TS 中:

this.registrationForm = new FormGroup({
       'languages': new FormArray([])
});
onAddLanguages() {
const control = new FormControl(null, Validators.required);
(<FormArray>this.registrationForm.get('languages')).push(control)
}
onDeleteLanguages(index) {
(<FormArray>this.registrationForm.get('languages')).removeAt(index)
}

【讨论】:

  • 你检查其他人的答案了吗????
  • 你为什么要问这个?
  • 你的答案和别人的答案有什么区别?
【解决方案4】:

您将 FormArray 命名为“Languages”而不是 LanguagesForm。

<div *ngFor="let Languages of registrationForm.controls.personalDetails.controls.Languages.controls; let i =index;">
      <input type="text" class="form-control" [formControlName]="i">
</div>

编辑: 我更改了 getLangsform 以及 &lt;mat-step&gt;&lt;form&gt; 标签。 https://stackblitz.com/edit/angular-lc8mu1

【讨论】:

  • formArray 的上父级呢???
  • 是的,我以为他只发布了一个代码 sn-p 而不是整个 app.component.html。你是对的 :) 他缺少 formGroup 和 formGroupName
  • 但你的回答是正确的,这是一个错字,会导致错误?
  • @StefanoM。我请检查我已更新的完整代码。谢谢。
  • @GRV 检查我的编辑 :)
猜你喜欢
  • 2019-08-25
  • 2018-06-11
  • 2021-12-25
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2020-09-07
  • 2021-06-22
  • 2021-07-10
相关资源
最近更新 更多