在Angular 7 中执行嵌套表单或嵌套表单组件的表单验证?
Perform form validation of nested form or nested form component in Angular 7?
我正在使用 Angular 7 和模板驱动表单。我在该表单中有 angular 表单,我正在调用另一个组件(或表单),并且我也在那里应用了必需的和 模板驱动的验证 。
另一种形式持有 Department Name
并且在创建 Student
时是 mandatory
。当所有必填字段都已填充后,我只想启用 save()
按钮。但是由于部门名称字段在不同的组件中,我将如何检查该字段是否已填充,现在我应该启用该按钮?
<div>
<form novalidate #f=ngForm>
<div style="position: relative;">
<div class="awr-input">
<label class="awr-inputbox-label">
Owner Name
<span class="awr-required">
<span aria-hidden="true">
*
</span>
</span>
</label>
<app-dept (selectedElement)=populateDepartment($event) [employeeName]=(student.studentName)></app-dept>
</div>
</div>
.....
.....
.....
<div class="fixed-bottom footer">
<div class="awr-container">
<div class="awr-row">
<div class="awr-col-12">
<div class="btn-group-2 float-right">
<div class="awr-cta float-right">
<div class="cta-with-icon">
<button type="submit" class="awr-btn awr-btn-primary" title="Submit" aria-label="Save" (click)="saveStudent()" [disabled]="!f.form.valid">
Save
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
dept.component.html
<form novalidate #f1=ngForm>
<div class="input-container">
<input type="text" id="" class="input-box" aria-required="true" minlength="0" maxlength="100" autocomplete="off"
width="0" min="" max="" step="" [(ngModel)]="inputField" name="inputField" (input)=getDept() required
#deptName="ngModel">
</div>
<div class="input-flydown flydownStyle" *ngIf="deptList?.length > 0">
<div>
<dl *ngFor="let dept of deptList">
<dt><a class="dxp-cta-link" (click)="sendDept(dept)">{{dept.name}}</a>
</dt>
<dd>{{dept.eId}} {{dept.jobTitle}}</dd>
</dl>
</div>
<div *ngIf="deptName.invalid && (deptName.dirty || deptName.touched)" class="dxp-error dxp-required">
Dept Name is mandatory.
</div>
</div>
</form>
我认为最简单的实现方式是使用 ViewChild
。您可以使用 templateRef
引用组件,然后检查该成员的值。
@ViewChild('appDept') appDept: DepartmentComponent;
// do/check stuff with this.appDept
<app-dept (selectedElement)=populateDepartment($event) [employeeName]=(student.studentName) #appDept></app-dept>
与其使用两种不同的形式,不如使用嵌套。
阅读更多here, written by the awesome guru Alexey Zuev
所以基本上只是在子组件中提供:
@Component({
// ...
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]
})
并在子模板中删除表单标签。父级将知道此子窗体以及子级中的窗体控件何时有效。
DEMO 与您的代码的剥离版本:STACKBLITZ
我正在使用 Angular 7 和模板驱动表单。我在该表单中有 angular 表单,我正在调用另一个组件(或表单),并且我也在那里应用了必需的和 模板驱动的验证 。
另一种形式持有 Department Name
并且在创建 Student
时是 mandatory
。当所有必填字段都已填充后,我只想启用 save()
按钮。但是由于部门名称字段在不同的组件中,我将如何检查该字段是否已填充,现在我应该启用该按钮?
<div>
<form novalidate #f=ngForm>
<div style="position: relative;">
<div class="awr-input">
<label class="awr-inputbox-label">
Owner Name
<span class="awr-required">
<span aria-hidden="true">
*
</span>
</span>
</label>
<app-dept (selectedElement)=populateDepartment($event) [employeeName]=(student.studentName)></app-dept>
</div>
</div>
.....
.....
.....
<div class="fixed-bottom footer">
<div class="awr-container">
<div class="awr-row">
<div class="awr-col-12">
<div class="btn-group-2 float-right">
<div class="awr-cta float-right">
<div class="cta-with-icon">
<button type="submit" class="awr-btn awr-btn-primary" title="Submit" aria-label="Save" (click)="saveStudent()" [disabled]="!f.form.valid">
Save
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
dept.component.html
<form novalidate #f1=ngForm>
<div class="input-container">
<input type="text" id="" class="input-box" aria-required="true" minlength="0" maxlength="100" autocomplete="off"
width="0" min="" max="" step="" [(ngModel)]="inputField" name="inputField" (input)=getDept() required
#deptName="ngModel">
</div>
<div class="input-flydown flydownStyle" *ngIf="deptList?.length > 0">
<div>
<dl *ngFor="let dept of deptList">
<dt><a class="dxp-cta-link" (click)="sendDept(dept)">{{dept.name}}</a>
</dt>
<dd>{{dept.eId}} {{dept.jobTitle}}</dd>
</dl>
</div>
<div *ngIf="deptName.invalid && (deptName.dirty || deptName.touched)" class="dxp-error dxp-required">
Dept Name is mandatory.
</div>
</div>
</form>
我认为最简单的实现方式是使用 ViewChild
。您可以使用 templateRef
引用组件,然后检查该成员的值。
@ViewChild('appDept') appDept: DepartmentComponent;
// do/check stuff with this.appDept
<app-dept (selectedElement)=populateDepartment($event) [employeeName]=(student.studentName) #appDept></app-dept>
与其使用两种不同的形式,不如使用嵌套。
阅读更多here, written by the awesome guru Alexey Zuev
所以基本上只是在子组件中提供:
@Component({
// ...
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]
})
并在子模板中删除表单标签。父级将知道此子窗体以及子级中的窗体控件何时有效。
DEMO 与您的代码的剥离版本:STACKBLITZ