【问题标题】:Angular 6 Form Array cannot be accessed inside an ng-containerAngular 6 Form Array 无法在 ng-container 中访问
【发布时间】:2019-08-16 21:42:48
【问题描述】:

我有一个 ng-container,它描述了我所有可能的表单字段模板,基本上是在一个大型 switch 语句上,具体取决于字段的元数据:

<ng-template #dynamicFormField let-field="inputField">
  <div *ngIf="field.dataTypeName == 'ShortText'">
    <mat-form-field class="col-md-6">
      <input matInput type="text" [placeholder]="field.attributeLabel" [formControlName]="field.attributeName">
    </mat-form-field>
  </div>

  <div *ngIf="field.dataTypeName == 'LongText'">
    <mat-form-field class="col-md-12">
      <input matInput type="text" [placeholder]="field.attributeLabel" [formControlName]="field.attributeName">
    </mat-form-field>
  </div>

  <div *ngIf="field.dataTypeName == 'Number'">
    <mat-form-field>
      <input matInput type="number" [placeholder]="field.attributeLabel" [formControlName]="field.attributeName">
    </mat-form-field>
  </div>
<ng-template>

我有一个基本的表单组,那么表单组的一个属性是一个表单数组,其中的每个元素都有自己的表单组。例如,数据模型如下所示:

{
  name: 'Article Name',
  description: 'Some description of the article',
  sections: [
    {
      sectionName: 'Rich text section',
      sectionContent: 'Some rich text'
    },
    {
      sectionName: 'Second section',
      sectionContent: 'Some rich text'
    }
  ]
}

其中每个字段都有描述其表单属性的相应元数据。

我希望能够在基本表单组和表单数组中的表单组中重用输入 switch 语句。但是,ng-container 内部无法访问由 formarray 的 formGroupName 输入指定的表单组:

<div *ngFor="let field of this.sectionTypeSchemas[section.value.sectionTypeId]">
  <div *ngIf="field.isVisible != false" formGroupName="{{i}}">
    <ng-container *ngTemplateOutlet="dynamicFormField;context:{ inputField:field }"></ng-container>
  </div>
</div>

我遇到的错误基本上是Angular找不到formarray的FormGroups内部的控件(即数据模型中的sectionName),尽管找到与基本formgroup控件对应的控件(名称和数据模型的描述)。有没有办法可以手动将表单组引用传递给 ng-container?一个简短的例子可以看到here

【问题讨论】:

  • 为什么不为此使用带有 @Input() 装饰器的额外组件?
  • @MullisS 我试过了,但仍然没有办法显式地将表单组引用传递给它。您会遇到相同的上下文错误。
  • 你能在 stackblitz 上做一个最小的例子吗?
  • @MullisS 当然可以在这里查看:link。如您所见,字段呈现,但找不到与之关联的表单控件。
  • 即使 Erbenskönig 的答案是正确的,您也应该为此编写一个组件,因为您希望您的组件不知道表单的表单结构。看看这个:stackblitz.com/edit/…

标签: angular angular-reactive-forms ng-template ng-container


【解决方案1】:

首先,我可能会使用子组件,而不是上面 cmets 中建议的 ng-template。

不过,为了让您的示例正常工作,需要修复两件事

在另一个组件或 ng-template 中使用 FormControls

每次在 ng-template 中使用 formGroup 的 formControl 时,如果 form-tag 放置在 ng-template 之外,则需要确保在 ng-template 中添加具有 formGroup 绑定的标签.

在你的情况下有一些特别的东西,因为你的 ng-template 中的 formGroup 实际上是一个 subFormGroup - 每个 formArrayItem 的 formGroup

FormArray 绑定

如果您要绑定到 formArray,您需要记住,您需要外部控件上的 formArrayName 以及与索引的绑定。请看这里以获得进一步的解释:FormArray binding

还有一件事

你的 stackblitz 中有一个错字:secitonHeader 而不是 sectionHeader。


这是一个工作:stackblitz

【讨论】:

  • 我在stackoverflow.com/questions/56806982/… 也有类似的问题。你能看看你是否有任何嵌套反应表单的解决方案。该链接附有stackblitz
  • 是否有关于“每次在 ng-template 中使用 formGroup 的 formControl 时,需要确保添加具有 formGroup 绑定的标签”的官方声明? - 这同样适用于 [formGroupName]。我想要一些可重用的组件,有时有一个嵌套组,有时没有,而且它不起作用,这令人沮丧。
  • 我发现如果formControl在一个ng-template或者不同的组件里面有一个可重用的组件,你需要传入formGroup并将它添加到一个周围的元素中,比如一个div。我不太确定是否有官方声明。我会看看这个。我不明白你的问题。也许打开一个新问题(并提供一个 stackblitz 或 jsfiddle),我会看看它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多