Angular 5-使用模板驱动的表单进行动态表单验证

时间:2018-07-20 11:15:45

标签: angular forms typescript validation

我正在使用ngFor动态创建表单字段,并且每个字段都有唯一的name attr。我正在努力验证他们。 我的示例代码:

<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item">
        <input type="text" name="units-{{i}}" [(ngModel)]="dimension.units" 
        class="first-f" placeholder="# of units" required>
        <input type="text" name="width-{{i}}" [(ngModel)]="dimension.width" 
        class="second-f" placeholder="W" required>
        <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" 
        class="third-f" placeholder="H" required>
        <input type="text" name="length-{{i}}" [(ngModel)]="dimension.length" 
        class="forth-f" placeholder="L" required>
        <select class="five-f" name="unitType-{{i}}" [(ngModel)]="dimension.unitType" 
        required>
            <option>inches</option>
            <option>feet</option>
        </select>
        <div *ngIf="!units-{{i}}.valid && units-{{i}}.touched" class="text-danger text-left">
            <small *ngIf="units-{{i}}.errors.required">Field is required.</small>
        </div>
    </div>

2 个答案:

答案 0 :(得分:4)

以某种方式解决了这一问题,只需添加#units="ngModel"。我猜想Angular正在处理ngFor本身中的引用。效果很好:

<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item">
    <input type="text" name="units-{{i}}" #units="ngModel" [(ngModel)]="dimension.units" class="first-f" placeholder="# of units" required>
    <input type="text" name="width-{{i}}" [(ngModel)]="dimension.width" class="second-f" placeholder="W" required>
    <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" class="third-f" placeholder="H" required>
    <input type="text" name="length-{{i}}" [(ngModel)]="dimension.length" class="forth-f" placeholder="L" required>
    <select class="five-f" name="unitType-{{i}}" [(ngModel)]="dimension.unitType" required>
        <option>inches</option>
        <option>feet</option>
    </select>
    <div *ngIf="!units.valid && units.touched" class="text-danger text-left">
        <small># of units is required.</small>
    </div>
</div>

答案 1 :(得分:0)

您的示例是响应式表单处理的用例。请考虑使用表单数组和表单组:

<form formArrayName="formArray">
<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item" [formGroupName]="i">

        <input type="text" name="units-{{i}}" [formControlName]="'units'"
        class="first-f" placeholder="# of units" required>
        <input type="text" name="width-{{i}}" [formControlName]="'width'" 
        class="second-f" placeholder="W" required>
        <input type="text" name="height-{{i}}" [formControlName]="'height'" 
        class="third-f" placeholder="H" required>
        <input type="text" name="length-{{i}}" [formControlName]="'length'" 
        class="forth-f" placeholder="L" required>
        <select class="five-f" name="unitType-{{i}}" [formControlName]="'unitType'" 
        required>
            <option>inches</option>
            <option>feet</option>
        </select>
        <div class="text-danger text-left">
            <small *ngIf="formArrayName[i].errors.required">Field is required</small>
        </div>
    </div>
</form>

您的初始解决方案不起作用,因为!units-{{i}}.valid && units-{{i}}.touched"并未按预期导出到模板。如果您将其声明为模板变量,则可能会起作用:

    <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" 
    class="third-f" placeholder="H" required #templateVar="ngForm">
   <div *ngIf="templateVar.valid && templateVar.touched" class="text-danger text-left">
        <small *ngIf="templateVar.errors.required">Field is required.</small>
    </div>

但是模板变量名称不能动态创建,即不允许#DynamicVar-{{i}}