【问题标题】:Angular material: mat-error not showing despite true methods角材料:尽管使用了正确的方法,但未显示垫子错误
【发布时间】:2019-02-28 01:16:40
【问题描述】:

我有一个要验证的确认密码表单控件。

当密码与确认密码输入中的值不同时,我想显示我的 mat-error 元素。为此,我有一个名为equalPasswords() 的函数。如果函数相同,则我们收到 true,否则,我们收到 false。

<mat-form-field>
              <input matInput placeholder="Repeat password" [formControl]="password2" type="password">
              <mat-error *ngIf="password2.invalid && password2.hasError('required')">Password is required</mat-error>
              <mat-error *ngIf="!equalPasswords() && !password2.hasError('required')">Passwords need to match</mat-error>
</mat-form-field>

我检查了控制台,当我在密码框中输入两个不同的输入时,equalPasswords() 返回 false。但是它仍然没有在 DOM 中显示错误。

有人知道如何解决这个问题吗?

Signup.component.ts

@Component({
    selector: 'app-sign-up',
    templateUrl: 'sign-up.component.html',
    styleUrls: ['sign-up.component.css']
})

export class SignUpComponent implements OnInit {

    mySignupForm: FormGroup;
    countries = countries;
    uniqueUsernameMessage;
    uniqueEmailMessage;
    formSubmitted = false;
    @Output() closeSubmenu = new EventEmitter();
    @ViewChild('select') select;

    constructor(
        private authService: AuthenticationService,
        private route: Router,
        private navigationService: NavigationService){}

    get firstName() { return this.mySignupForm.get('firstName'); }
    get lastName() { return this.mySignupForm.get('lastName'); }
    get username() { return this.mySignupForm.get('username'); }
    get email() { return this.mySignupForm.get('email'); }
    get password1() { return this.mySignupForm.get('password1'); }
    get password2() { return this.mySignupForm.get('password2'); }
    get birthDate() { return this.mySignupForm.get('birthDate'); }
    get country() { return this.mySignupForm.get('country'); }
    get house() { return this.mySignupForm.get('house'); }

    ngOnInit() {
        this.mySignupForm = new FormGroup({
            firstName: new FormControl(null, Validators.required),
            lastName: new FormControl(null, Validators.required),
            username: new FormControl(null, [Validators.required, Validators.minLength(5), Validators.maxLength(15)]),
            birthDate: new FormControl(null, Validators.required),
            password1: new FormControl(null, [Validators.required, Validators.minLength(6), Validators.maxLength(15), Validators.pattern('^.*(?=.{4,10})(?=.*\\d)(?=.*[a-zA-Z]).*$')]),
            password2: new FormControl(null, Validators.required),
            email: new FormControl(null, [Validators.required, Validators.email]),
            country: new FormControl(null, Validators.required),
            house: new FormControl(null, Validators.required)
        })
    }

    equalPasswords() {

        console.log('equaltest', this.password1.value === this.password2.value);
        return this.password1.value === this.password2.value;
    }

}

【问题讨论】:

    标签: angular angular-material angular-reactive-forms


    【解决方案1】:

    我发现了一种可能发生这种情况的非常微妙的情况。

    如果您将[formGroup] 指令 放在&lt;div&gt; 之类的东西上,那么在提交表单时它不会得到submitted == true(它必须放在&lt;form&gt; 上才能发生这种情况)。

    提交的表单是显示错误的两个触发器之一 - 另一个是已触摸的字段。而touched 意味着onBlur,这意味着焦点一定是失去了

    所以你可以得到这种情况:

    • 你的 div 上有 [formGroup]
    • 您有类似用户名/密码表单的内容。
    • 您还有一个提交按钮。
    • 您输入两个字段并按回车键。
    • 您的验证触发了一个错误,但它没有显示!为什么!
    • 因为您从未blur-ed 密码字段(例如,您的光标仍在该框中)
    • 最简单的解决方案是只将[formGroup] 放在&lt;form&gt; 标签上
    • 另一种是创建自定义ErrorStateMatcher

    如果您将 formGroup 传递给“哑”子组件(没有自己的表单),则必须使用依赖注入并在构造函数中传递 FormGroupDirective

    【讨论】:

      【解决方案2】:

      MatFormField 仅在 FormControl 出现错误时显示 mat-error 元素。它不会仅仅因为您通过ngIfElse 告诉它而显示 - 这只会受表单控制状态的影响。解决此问题的一种方法是创建自定义验证器并使用它来检查密码是否匹配。您还可以通过 equalPasswords() 函数在字段上设置错误。应该是这样的:

      equalPasswords(): boolean {
      
          const matched: boolean = this.password1.value === this.password2.value;
      
          console.log('equaltest', matched);
      
          if (matched) {
              this.signupForm.controls.password2.setErrors(null);
          } else {
              this.signupForm.controls.password2.setErrors({
                 notMatched: true
              });
          }
      
          return matched;
      }
      

      【讨论】:

      • 干净完美!感谢分享!
      猜你喜欢
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 2016-12-28
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多