角度验证器被忽略或不起作用

问题描述 投票:0回答:1

我使用ReactiveForms。我有一个登录组件,其中使用两个输入字段(电子邮件和密码)。这些输入字段都来自同一个自定义组件“TextFieldComponent”。我尝试在电子邮件输入上添加特定的正则表达式验证器,并在密码输入上添加 minLength 验证器(仅用于测试)。当我输入有效的电子邮件地址时,我收到自定义错误消息“无效的电子邮件地址”,但事实不应如此。另外,对于密码输入,不考虑 minLength 验证器。

登录组件 TS:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../auth.service';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { LoginRequest } from 'src/app/shared/models/login-request';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  loginForm: FormGroup;

  ngOnInit(): void {
    this.createLoginForm();
  }

  createLoginForm(): void {
    this.loginForm = new FormGroup({
      email: new FormControl(null, [Validators.required, Validators.pattern(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/)]),
      password: new FormControl(null, [Validators.required, Validators.minLength(4)])
    });
  }
}

登录组件模板

<form (ngSubmit)="onSubmit()" [formGroup]="loginForm" class="form-signin">
    <h1 class="h3 mb-3 font-weight-normal text-center">Please sign in</h1>

    <app-text-input
        [formControlName]="'email'"
        [label]="'Email address'">
    </app-text-input>

    <app-text-input
        [formControlName]="'password'"
        [label]="'Password'"
        [type]="'password'">
    </app-text-input>

    <app-button [disabled]="loginForm.invalid" type="submit" label="Sign in" className="btn btn-primary w-100" class="w-100"></app-button>
</form>

TextFieldComponent TS

import { Component, ElementRef, Input, Self, ViewChild } from '@angular/core';
import { AbstractControl, NgControl } from '@angular/forms';

@Component({
  selector: 'app-text-input',
  templateUrl: './text-input.component.html',
  styleUrls: ['./text-input.component.scss']
})
export class TextInputComponent {
  @ViewChild('input', {static : true}) input: ElementRef; // reference to the input field
  @Input() type : 'email' | 'text' | 'password' = 'text'; // input type (password, text, date, button, ...)
  @Input() label: string; // Label that describes the input field

  constructor(
    @Self() public controlDir: NgControl
  ) {
    // Bind the valueAccessor to this particular class, which lets us access the control directive inside our component + template
    this.controlDir.valueAccessor = this;
  }

  ngOnInit(): void {
    const control = this.controlDir.control as AbstractControl;
    control.updateValueAndValidity();
  }

  onChange(event? : any) { }

  onTouched(event? : any) {}

  writeValue(obj: any): void {
    this.input.nativeElement.value = obj || '';
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}

TextField组件模板

<div class="form-label-group">

<label for="{{label}}">{{label}}</label>
<input #input [ngClass]="(controlDir && controlDir.control && controlDir.control.touched) 
        ? !controlDir.control.valid 
        ? 'is-invalid' 
        : 'is-valid' 
        : null" [type]="type" (input)="onChange($event)" (blur)="onTouched()" id="{{label}}"
    class="form-control" placeholder="{{label}}" autocomplete="off" >

<!-- Synchornous Error Messages -->

<!-- Invalid control check -->
<div *ngIf="(
    controlDir && 
    controlDir.control &&
    !controlDir.control.valid &&
    controlDir.control.touched
    )" class="invalid-feedback">

    <!-- Required control check -->
    <span *ngIf="controlDir.control.errors?.['required']">{{label}} is required</span>

    <!-- Pattern control check -->
    <div *ngIf="controlDir.control.errors?.['pattern']">Invalid Email Format</div>


</div>

有人知道我的验证器出了什么问题以及为什么它们没有按预期工作吗?

angular angular-reactive-forms
1个回答
0
投票

问题出在自定义表单控件上。

你有:

<input #input ... (input)="OnChange($event)">

$event 是一个输入事件,你应该使用

<input #input ... (input)="onChange(input.value)">

或创建一个函数

  change(event:any)
  {
    this.onChange(event.target.value)
  }
  //and use
   <input #input ... (input)="change($event)">

提示:有时,要检查 FormGroup 是否可以在 .html 中写入(在本例中是在您的登录组件中)

<pre>
  {{loginForm.value|json}}
</pre>
© www.soinside.com 2019 - 2024. All rights reserved.