web-dev-qa-db-ja.com

Angularマテリアル:真のメソッドにもかかわらずマットエラーが表示されない

確認したい確認パスワードformcontrolがあります。

パスワードがパスワードの確認入力の値と同じでない場合、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>

コンソールを確認し、パスワードボックスに2つの異なる入力を入力すると、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;
    }

}
6
tilly

MatFormFieldは、FormControlにエラーがある場合にのみ_mat-error_要素を表示します。 ngIfElseを介して指示したからといって表示されません。これはフォームコントロールの状態に従ってのみ機能します。この問題を解決する1つの方法は、カスタムバリデーターを作成し、それを使用してパスワードが一致することを確認することです。 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;
}
_
5
G. Tranter

これが発生する非常に微妙な状況を発見しました。

[formGroup]directive<div>のようなものに置くと、フォームが送信されたときにsubmitted == trueを取得しません(フォームを送信するには<form>にある必要があります)。

送信されるフォームは、エラーを表示するための2つのトリガーの1つです。もう1つは、フィールドがタッチされたことを示します。そしてtouchedはonBlurを意味し、これはフォーカスがlostであったに違いないことを意味します。

だからあなたはこの状況を得ることができます:

  • Divに[formGroup]があります
  • あなたはユーザー名/パスワードフォームのようなものを持っています。
  • 送信ボタンもあります。
  • 両方のフィールドに入力してEnterキーを押します。
  • 検証によりエラーが発生しますが、表示されません!なぜ!
  • パスワードフィールドをblur- edしたことがないため(たとえば、カーソルがまだそのボックス内にある)
  • 最も簡単な解決策は、[formGroup]タグにのみ<form>を付けることです
  • もう1つは、カスタムを作成することです ErrorStateMatcher

formGroupを「ダム」の子コンポーネント(独自のフォームを持たない)に渡す場合は、依存関係注入を使用し、代わりにコンストラクタでFormGroupDirectiveを渡す必要があります。

0
Simon_Weaver