【问题标题】:Angular2 Nested formGroups - formArrays and template BindingAngular2嵌套formGroups - formArrays和模板绑定
【发布时间】:2017-04-21 22:45:56
【问题描述】:

问题来了:

我有一个带有嵌套表单组的复杂表单,这是一个“简化”的结构:

-> MyForm (formGroup)
    -> Whatever01 (formControl - input)
    -> Whatever02 (formControl - input)
    -> WhateverGroup01 (formGroup)
        -> Whatever03 (formControl - input)
        -> Whatever04 (formControl - input)
    -> WhateverArray01 (formArray)
        -> WhateverGroup02 (formGroup)
            -> Whatever05 (formControl - input)
            -> WhateverGroup03 (formGroup)
                -> Whatever06 (formControl - input)
        -> WhateverGroup04 (formGroup)
            -> Whatever07 (formControl - input)
    -> ...

角度方面,它应该看起来像这样(不正确/不完整,只是提供一个想法):

this.myForm = this.fb.group({
    whatever01: ['',Validators.compose([...])],
    whatever02: ['',Validators.compose([...])],
    whateverGroup01: this._formBuilder.group({
        whatever03: ['',Validators.compose([...])],
        whatever04: ['',Validators.compose([...])]
    }),
    whateverArray01: this._formBuilder.array([
        this._formBuilder.group({
            whatever05: ['',Validators.compose([...])],
            whateverGroup03: this._formBuilder.group({
                whatever06: ['',Validators.compose([...])]
            })
        }),
        this._formBuilder.group({
            whatever07: ['',Validators.compose([...])],
        })
    ])
    ...
});

从根 myForm 项目到获取 formArray 一切都很好,但是麻烦来了....

所以,我无法访问“whatever05”(并且 06 但 05 不起作用......所以......) formControl 将其绑定到模板!这是模板的实际外观(故意跳过了数组之前的部分),有趣的部分是 [????]="???",这实际上是问题所在。

<form [formGroup]="myForm" ...>
    <!-- ...skipped... -->
    <div formArrayName="whateverArray01" *ngFor="let item of myForm.controls.whateverGroup01.controls.whateverArray01.controls;let idx = index;" [formGroupName]="idx">
        <div [????]="????">
            <input formControlName="whatever05" ... />
            <div [????]="????">
                <input formControlName="whatever06" ... />
            </div>
        </div>    
    </div>
</form>

位于 formArray 中的 formGroups 具有相同的结构。

基本上,问题是我无法访问 formGroups 中的 formControls...

我尝试了几种解决方案,我使用了 [formGroupName]、formGroupName(不带括号)、[formGroup]、formControlName,...但无法弄清楚我必须使用什么才能将相应的 formGroup/formControl 与数据 !

我现在遇到这种错误:

formGroup expects a FormGroup instance. Please pass one in. 
// This when using [formGroup]="item.whateverGroup02"

Cannot find control with name: 'whatever05'
// When using [formGroup]="item.controls.whateverGroup02"

Cannot find control with path: 'whateverArray01 -> 0 ->'
// This when using [formGroupName]="whateverGroup02"

感谢阅读/帮助

这里有一些代码:

http://plnkr.co/edit/wf7fcHMkhIwzmLWLnCF8?p=preview

【问题讨论】:

  • formArrayName 需要在 formGroupName 的包装元素中。
  • 还有这里的野兽myForm.controls.whateverGroup01.controls.whateverArray01.controls可以浓缩成myForm.get('whateverGroup.whateverArray').
  • 另外我认为 FormArray 需要有相同的嵌套 FormGroups。
  • 嗨!感谢 cmets,formArray 中的我的 formGroups 都具有相同的结构。这不会是一个问题。我不明白您在第一条评论中的意思...
  • 在你上面的例子中不一样。我的意思是你在同一个元素中声明 formArrayName 和 formGroupName 。将 formArrayName 移动到更高的元素。

标签: javascript html angular typescript angular2-forms


【解决方案1】:

您的表单构建对我来说似乎是正确的。你的模板有问题,你的FormArray的迭代不正确,你的FormArray不在FormGroupWhateverGroup01里面,所以迭代应该是这样的:

*ngFor="let ctrl of myForm.controls.whateverArray01.controls;

FormArray 的模板部分应该是这样的:

<div *ngFor="let ctrl of myForm.controls.whateverArray01.controls; let i = index" [formGroupName]="i">
   <input formControlName="whatever05" />
   <div formGroupName="whateverGroup03">
      <input formControlName="whatever06" />
   </div>
</div>

这应该可以解决问题:)

这是一个

Demo

【讨论】:

  • 嗯,这是一个很好的观点,但这并不能完全解决我的问题。我没有这个嵌套问题。但你是对的,这是我的副本中的一个错误......我用“不工作”的plunker更新了这个问题。谢谢:)
【解决方案2】:

首先你的视图绑定错误:

[formGroupName]="whateverGroup02"

您的组件中没有 whateverGroup02 属性。我们应该按如下方式传递字符串:

formGroupName="whateverGroup02"

那么如果你建立这样的组:

this.fb.group({
  x: 1,
  y: {
    z: 2
  }
})

你会得到

FormGroup
  -> FormControl with name `x` and value `1`   
  -> FormControl with name `y` and value `{ z: 2 }`

这意味着如果你想操作嵌套的表单组,你必须创建它们。 即

let fGroups = data.map(rs => this.buildFormGroup(rs));
...
buildFormGroup(obj) {
  let formGroup: { [id: string]: AbstractControl; } = {};
  Object.keys(obj).forEach(key => {
    formGroup[key] = typeof obj[key] === 'object' ?
      this.buildFormGroup(obj[key]) : 
      new FormControl(obj[key]);
  });
  return this._formBuilder.group(formGroup);
}

Plunker Example

【讨论】:

  • 您好!感谢您的回复!查了一下例子,这实际上解决了formGroup的问题,但是如果还有嵌套的formArrays呢?我应该添加一个“buildFormArray”函数还是什么?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 2016-11-29
  • 2017-01-07
  • 1970-01-01
  • 2011-10-29
相关资源
最近更新 更多