首页 文章

当返回到较旧的步骤时,Angular Material Stepper会使mat-formfield验证动态表单

提问于
浏览
1

使用动态表单时,角度材料 mat-stepper 会出现问题 . 例如,我有一个步进器,有3个步骤,每个步骤都有自己的形式 . 然而,第一步使用隐藏表单来确定它是否有效,因为此步骤可以动态添加更多表单,因此将所有表单绑定到步骤是不可能的 .

当您处于第一步时,您可以创建多个表单,一切都按预期工作,而不会对添加的新表单进行任何随机验证 . 如果您转到步骤2或3并返回到第一步,然后创建一个新表单,它将自动启动,所有字段突出显示为红色,则会出现此问题 .

我已经尝试了许多不同的尝试来压制但是我没有成功 . 下面是我的第一步如何包含绑定到步骤控件的hiddenForm,默认表单和在该步骤中创建更多表单的按钮的基本示例 .

我试图解决这个问题的研究让我相信材料步进器会使所有的mat-form-fields变为红色,如果无效,无论是否新添加 .

<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>

试图尝试失败:(当前表单是新添加的表单)

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 )

1 回答

  • 1

    背景资料

    我找到的最好的解决方案是更改 mat-stepper 上的参数 . 在任何给定时间都选择了一个步骤 . 在步骤中,您可以更改步骤是否已与之交互 . 如果先前已访问过步骤,则 interacted 参数将设置为true . 由于这是有意义的并且有意义,但是它会导致向所有 mat-form-fields 添加一个类导致它们变红的问题 .

    这会导致糟糕的用户体验的场景:

    • 完成第一步并转到第二步 . 进入第二步后,您会发现第一步出错并决定返回第一步 . 您进行了更改,现在再次进行第二步 . 因为您已经访问过此步骤,如果您有 mat-form-fields 将添加一个类(可能还有其他更改),并且您的表单字段现在全部为红色 . 这是一种糟糕的用户体验,因为用户在技术上没有犯任何错误并且可能过度承受 .

    • 在第一步中,您可以在创建动态表单的位置使用它 . 为简单起见,请使用英雄之旅类比 . 在第一步中,您可以动态添加表单 . 每个表单代表您要添加的新英雄 . 你已经添加了3个英雄并继续前进到第2步 . 在完成第2步之前你意识到你忘记了一些英雄并继续回到第1步 . 现在,当你点击我们的按钮'create hero'时,你的动态表格会弹出,但你所有的 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>
    

    hero.stepper.ts

    export class heroStepComponent implements OnInit {
      constructor(){
        ...
      }
    
      ngOnInit(){
        ...
      }
    
      stepChanged(event, stepper){
        stepper.selected.interacted = false;
      }
    }
    

相关问题