如何在Angular中获取嵌套的FormGroup控件

78

https://angular.io/api/forms/FormGroup#controls

根据我的表单:

this.form= this.fb.group({
  id: ['', [Validators.required]],
  name: ['', [Validators.maxLength(500)]],
  child: this.fb.group({
    id: [ '', [Validators.required]],
    name: ['']
  })
});

我想要获取子项的有效性,就像 this.form.controls.child.controls.valid 一样,在这个 FormGroup API 中,.controls 返回的是 AbstractControl。

Angular 编译错误,错误 TS2339:属性“controls”在类型“AbstractControl”上不存在。

5个回答

147

你离成功已经很接近了。请看下面的代码示例或在我创建的非常简单(但丑陋)的StackBlitz中尝试操作。

StackBlitz演示

在你的模板中确保添加了子表单组。

<div>
  <form [formGroup]="myForm" (ngSubmit)="send()">
    <input type="text" name="name" formControlName="name">
    <div formGroupName="child">
       <input type="text" name="id" formControlName="id">
       <input type="text" name="name" formControlName="name">
    </div>
    <button class="btn btn-primary">send</button>
  </form>
</div>

然后在你的组件中,你可以像这样访问表单字段。

this.myForm['controls'].child['controls'].id.valid

我为这个示例创建的响应式表单:

this.myForm = this.fb.group({
      name: ['', [Validators.maxLength(500)]],
      child: this.fb.group({
        id: ['', [Validators.required]],
        name: ['']
      })
    });

**2019年12月更新**

this.myForm.get('child.id').valid

我的原始回答有点过时了。现在有一种更简洁的方法可以实现这个功能!以下是更简洁解决方案示例代码。

3
好的,那是一个讨厌的 Angular Bug。看更新后的答案,使用 this.myForm['controls'].child['controls'].id.valid 来代替。 - Narm
1
太好了!你是对的。然后我找到了另一种解决问题的方法,将 this.form.controls.child 的类型转换为 FormGroup。 - soulxy
1
太棒了,很高兴它起作用了。而且,那也是一个巧妙的解决方案!你应该更新你的问题,更具体地描述你需要解决的错误,这样任何遇到相同问题的人都能找到解决方案。现在写的有点模糊,但这是一个非常有效的问题。 - Narm
如何对嵌套的FormGroup项执行setValidators函数。 - Manoj Sanjeewa
@Narm,我在Angular嵌套表单控件方面遇到了一些问题,你能帮我解决吗?这是我的问题链接,感谢你抽出时间。 https://stackoverflow.com/questions/59324879/i-am-using-formarray-and-i-have-controls-inside-another-controls-but-how-can-i-a - abubakkar tahir
显示剩余4条评论

30

从AbstractControl的用法注释中可以发现,在一个嵌套的FormGroup中获取FormControl有几种非常简单的方法:

检索嵌套控件

例如,要获取person子组中嵌套的name控件:

this.form.get('person.name');

- 或 -

this.form.get(['person','name']);


请参考 Angular 文档中的链接以获取更多信息:https://angular.cn/api/forms/AbstractControl#get - David Meza

11
userForm=new FormGroup({
    fName:new FormControl('',Validators.required),
    lName:new FormControl(),
    eMail:new FormControl('',[Validators.email,Validators.required]),
    qualificationForm:new FormGroup({
     perS:new FormControl(''),
     perHs:new FormControl('')
    })
});

save(){
  console.log(this.userForm.get("qualificationForm.perS").value);
}

请回答与Angular 14中的表单验证相关的**这个问题**。谢谢! - Razvan Zamfir

7

我经常使用的一种方法是将子FormGroup转换为FormGroup,因为'get('control')'方法返回一个AbstractControl,然后使用'get()'方法访问子FormGroup选项,如下所示:

(this.form.get('child') as FormGroup).get('id').valid

6

我有以下表格:

registerLibrarianForm = this.formBuilder.group({
       firstName: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(128), Validators.pattern(this.nameRegex)]],
       lastName:  ['', [Validators.required, Validators.minLength(2), Validators.maxLength(128), Validators.pattern(this.nameRegex)]],
       address: this.formBuilder.group({
         country: ['', [Validators.required]],
         city: ['', [Validators.required]]})})

我获取主窗体(registerForm)的控件是通过创建一个简单的返回方法来实现的:
get controls(){
return this.registerForm.controls;
}

我获取嵌套表单(地址)的控件的方法是创建另一个方法:

get addressControls(){
return ((this.registerForm.get('address') as FormGroup).controls)
}

因此,如果您需要在主表单的HTML中执行*ngIf,请使用第一种方法。

*ngIf="controls.firstName.errors && ...

关于嵌套表单:

*ngIf="addressControls.country.errors && ...

我希望这可能会有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接