L1g*_*ira 5 validation dynamic dynamic-forms angular-material angular
mat-stepper
使用动态模板时,角材出现问题。例如,我有一个具有3个步骤的步进器,每个步骤都有自己的形式。但是,第一步使用隐藏表单来确定它是否有效,因为此步骤可以动态添加更多表单,因此将所有表单绑定到该步骤是不可能的。
第一步时,您可以创建多个表单,并且一切都会按预期进行,而不会对添加的新表单进行任何随机验证。如果您转到步骤2或3,然后回到第一步,然后创建一个新表单,它将自动以所有突出显示为红色的字段开始,就会出现问题。
我尝试了多种尝试来压制,但是我没有成功。下面是一个基本示例,说明我的第一步如何包含与步骤控件绑定的hiddenForm,默认表单以及在该步骤中创建更多表单的按钮。
我试图解决此问题的研究使我相信,无论是否新添加,材料步进器都会使所有垫形场变为红色(如果无效)。
<mat-horizontal-stepper [linear]="true">
<mat-step [stepControl]="hiddenForm" label="step 1"
<form [formGroup]="myForm">
<mat-form-field>
<mat-label>
First Name
</mat-label>
<input [formControl]="firstName"matInput>
<mat-error *ngIf="!firstName.valid && firstName.touched">
First Name required
</mat-error>
</mat-form-field>
</form>
<button (click)="AddNewForm()">Add New Form</button>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
尝试失败的尝试:(当前表单是新添加的表单)
this.currentForm.markAsUntouched();
this.currentForm.markAsPristine();
this.currentForm.setErrors(null);
this.currentForm.reset();
this.currentForm.get('firstName).setErrors(null);
this.currentForm.get('firstName).reset();
this.currentForm.get('firstName).markAsPristine();
this.currentForm.get('firstName).markAsUntouched();
<mat-step [completed]="true" ..> ( on all steps )
Run Code Online (Sandbox Code Playgroud)
我发现最好的解决方案是更改上的参数mat-stepper
。在任何给定时间都会选择一个步骤。在步骤中,您可以更改步骤是否已交互。如果先前已访问过某个步骤,则该interacted
参数将设置为true。这样做是有意的,但是会给所有类添加一个类,mat-form-fields
导致它们变红。
您完成第一步,然后转到第二步。转到第二步后,您意识到您在第一步中犯了一个错误,并决定导航回第一步。您进行了更改,然后再次进行第二步。因为您已经访问过此步骤,所以如果您有mat-form-fields
一个班级(可能会进行其他更改),那么您的表单字段将全部变为红色。这是糟糕的用户体验,因为从技术上讲,用户没有犯任何错误,并且可能会过度负担。
在第一步中,您将在其中创建动态表单。为了简单起见,让我们使用英雄之旅类比。在第一步中,您可以动态添加表单。每个表格代表您要添加的新英雄。您已经添加了3个英雄,然后继续执行第2步。在完成第2步之前,您意识到您已经忘记了几个英雄,然后返回到第1步。现在,当您单击“创建英雄”按钮时,会弹出动态表单,但是mat-form-fields
现在所有红色,就像用户犯了一个错误。这是另一个糟糕的用户体验。
hero.stepper.html
<mat-horizontal-stepper [linear]="true"
(selectionChange)="stepChanged($event, stepper);">
<mat-step [stepControl]="hiddenForm" label="step 1"
<form [formGroup]="heroFormGroupArray[0]">
<mat-form-field>
<mat-label>Hero Name</mat-label>
<input [formControl]="heroName"matInput>
...
</mat-form-field>
</form>
<button (click)="AddNewHero()">Add New Hero</button>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
英雄步进
export class heroStepComponent implements OnInit {
constructor(){
...
}
ngOnInit(){
...
}
stepChanged(event, stepper){
stepper.selected.interacted = false;
}
}
Run Code Online (Sandbox Code Playgroud)
继上一篇文章后,我发现了 stepChanged 函数的更好实现:
stepChanged(event: StepperSelectionEvent) {
if (event.previouslySelectedIndex > event.selectedIndex) {
event.previouslySelectedStep.interacted = false;
}
}
Run Code Online (Sandbox Code Playgroud)
此代码将仅在您从前面的步骤转到的步骤上设置交互属性。
归档时间: |
|
查看次数: |
3122 次 |
最近记录: |