【问题标题】:Access dynamic nested reactive form controls for validation访问动态嵌套反应式表单控件以进行验证
【发布时间】:2022-12-06 21:03:39
【问题描述】:

stackblitz demo

我有一个嵌套的表单控件,它在大约 3 个 *ngFor 循环中构建页面结构。下面的例子是最终循环:

<ng-container *ngFor="let data of tabsAndPills[tab][pill]; let i = index">
...

<input [required]="data['isMandatory']" type="text" [formControlName]="data['name']" />

这些循环构建了我的表单控件,因此我无法对任何验证消息进行硬编码。我想在每个控件下添加一些文本来表示“必需” - 当控件为空时(如果删除 stackblitz demo 中的姓氏字段值,整个表单将变得无效,这是正确的,但我想挂钩该特定控件以启用以下文本)。例如

<div *ngIf="data['name'].invalid">{{ data['displayName'] }} is required</div>

我需要在我的表单中寻找 [formControlName]="data['name']" 的动态控件,因此查看它是否无效或不显示文本。我想我需要做一些像这个模板方面的事情......

*ngIf="form.controls.fields['controls'].tab['controls'].pill['controls'].data['name'].invalid"

但是做不对,tabpill的循环let在上述格式中无法识别。或者,有没有一种方法可以使用 getter 来简化此操作?

stackblitz demo

【问题讨论】:

    标签: angular forms validation angular-reactive-forms


    【解决方案1】:

    要在多个ngFor 循环中访问嵌套表单控件,您可以使用FormGroup 类提供的get() 方法。此方法允许您通过表单组中的路径检索表单控件,表单组由您传递给 get() 方法的键序列定义。

    下面是一个示例,说明如何使用 get() 方法访问多个 ngFor 循环中的嵌套表单控件:

    <ng-container *ngFor="let tab of tabsAndPills; let tabIndex = index">
      <ng-container *ngFor="let pill of tab['controls']; let pillIndex = index">
        <ng-container *ngFor="let data of pill['controls']; let dataIndex = index">
          <input
            [required]="data['isMandatory']"
            type="text"
            [formControlName]="data['name']"
          />
          <div *ngIf="form.get(['controls', tabIndex, 'controls', pillIndex, 'controls', dataIndex, 'name']).invalid">
            {{ data['displayName'] }} is required
          </div>
        </ng-container>
      </ng-container>
    </ng-container>
    
    

    在此代码中,我们使用 get() 方法检索与嵌套的 ngFor 循环中的当前 data 项对应的表单控件。我们使用当前的tabIndexpillIndexdataIndex值构造表单组内表单控件的路径,并将此路径传递给get()方法。这允许我们访问表单控件并判断它是否无效,以便我们显示相应的错误信息。

    您还可以使用 get() 方法来简化 ngIf 条件,方法是将 get() 调用的结果存储在本地模板变量中。这是一个例子:

    <ng-container *ngFor="let tab of tabsAndPills; let tabIndex = index">
      <ng-container *ngFor="let pill of tab['controls']; let pillIndex = index">
        <ng-container *ngFor="let data of pill['controls']; let dataIndex = index">
          <input
            [required]="data['isMandatory']"
            type="text"
            [formControlName]="data['name']"
          />
          <ng-container *ngIf="(control = form.get(['controls', tabIndex, 'controls', pillIndex, 'controls', dataIndex, 'name']))">
            <div *ngIf="control.invalid">
              {{ data['displayName'] }} is required
            </div>
          </ng-container>
        </ng-container>
      </ng-container>
    </ng-container>
    
    

    在这段代码中,我们使用get()方法检索与当前data项对应的表单控件,并将结果存储在名为control的本地模板变量中。这允许我们简化ngIf条件,我们现在可以简单地检查control是否无效,而不需要使用表单控件的完整路径。这可以使代码更易于阅读和理解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多