表单验证 Angular 4

Form Validation Angular 4

因此,我尝试使用以下示例: https://github.com/agiratech/angular4-reactive-form-exercise2/

但是,当我实施它并提交我的表单时,屏幕上的任何地方都没有显示任何错误。您将在下面找到我能想到的所有相关代码。我正在寻找如何让错误显示在屏幕上。我是 Angular 4 的新手,如有任何帮助,我们将不胜感激。

pages.module.ts

import ...
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import ...

import { RegisterComponent } from './register/register.component';
import ...
import { ErrorsComponent } from '../errors.component';

@NgModule({
    imports: [
        CommonModule,
        RouterModule.forChild(PagesRoutes),
        FormsModule,
        ReactiveFormsModule
    ],
    declarations: [
        LoginComponent,
        RegisterComponent,
        LockComponent,
        ErrorsComponent
    ]
})

export class PagesModule {}

register.component.ts

import ...
import {FormGroup, FormBuilder, Validators, FormControl, NgForm} from '@angular/forms';
import ...
import { CustomValidators } from "../../validators/custom-validator.directive";

declare var $:any;

@Component({
    moduleId:module.id,
    selector: 'register-cmp',
    templateUrl: './register.component.html'
})

export class RegisterComponent implements OnInit{
    registerForm: FormGroup;
    test : Date = new Date();
    loading = false;
    error = '';

    constructor(
        private form: FormBuilder,
        private router: Router,
        private authenticationService: AuthenticationService)
    {
        this.registerForm = new FormGroup ({
            'username':new FormControl('', Validators.required),
            'email': new FormControl('', [Validators.required, CustomValidators.validEmail]),
            'first_name': new FormControl('', Validators.required),
            'last_name': new FormControl('', Validators.required),
            'password': new FormControl('', Validators.required),
            'confirmPassword': new FormControl('', Validators.required)
        });
    }


    checkFullPageBackgroundImage(){
        var $page = $('.full-page');
        var image_src = $page.data('image');

        if(image_src !== undefined){
            var image_container = '<div class="full-page-background" style="background-image: url(' + image_src + ') "/>'
            $page.append(image_container);
        }
    };

    ngOnInit() {


        this.checkFullPageBackgroundImage();

        setTimeout(function(){
            // after 1000 ms we add the class animated to the login/register card
            $('.card').removeClass('card-hidden');
        }, 700)
    }

    register(registerForm: NgForm) {
        console.log(this.registerForm.value);
    }


}

register.component.html

<form [formGroup]="registerForm" (ngSubmit)="register(registerForm)">
        <div class="card card-plain">
        <div class="content">
         <div class="form-group">
              <input type="text" placeholder="Your First Name" class="form-control" formControlName="first_name">
              <errors [control]="registerForm.controls.first_name"></errors>
         </div>
         <div class="form-group">
              <input type="text" placeholder="Your Last Name" class="form-control" formControlName="last_name">
              <errors [control]="registerForm.controls.last_name"></errors>
         </div>
         <div class="form-group">
              <input type="text" placeholder="Username" class="form-control" formControlName="username">
              <errors [control]="registerForm.controls.username"></errors>
         </div>
         <div class="form-group">
              <input type="email" placeholder="Enter email" class="form-control" formControlName="email">
              <errors [control]="registerForm.controls.email"></errors>
         </div>

         <div class="form-group">
             <input type="password" placeholder="Password" class="form-control" formControlName="password">
             <errors [control]="registerForm.controls.password"></errors>
         </div>
         <div class="form-group">
             <input type="password" placeholder="Password Confirmation" class="form-control" formControlName="confirmPassword">
             <errors [control]="registerForm.controls.confirmPassword"></errors>
         </div>
             </div>
             <div class="footer text-center">
                 <button [disabled]="loading" type="submit" class="btn btn-fill btn-neutral btn-wd">Create Account</button>
                <i *ngIf="loading" class="fa fa-spinner fa-spin fa-fw"></i>
             </div>
             <errors [control]="registerForm"></errors>
         </div>
    </form>

errors.component.ts

import { Component, Input } from '@angular/core';
import { AbstractControlDirective, AbstractControl } from '@angular/forms';

@Component({
  selector: 'errors',
  template: `
    <ul *ngIf="showErrors()">
      <li class="help-box text-warning" *ngFor="let error of errors()">{{error}}</li>
    </ul>
  `,
})
export class ErrorsComponent {

  private static readonly errorMessages = {
    'required': () => 'This field is required',
    'minlength': (params) => 'The min number of characters is ' + params.requiredLength,
    'maxlength': (params) => 'The max allowed number of characters is ' + params.requiredLength,
    'pattern': (params) => 'The required pattern is: ' + params.requiredPattern,
    'age': (params) => params.message,
    'validEmail': (params) => params.message
  };

  @Input()
  private control: AbstractControlDirective | AbstractControl;

  showErrors(): boolean {
    return this.control &&
      this.control.errors &&
      (this.control.dirty || this.control.touched);
  }

  errors(): string[] {
    return Object.keys(this.control.errors)
      .map(field => this.getMessage(field, this.control.errors[field]));
  }

  private getMessage(type: string, params: any) {
    return ErrorsComponent.errorMessages[type](params);
  }

}

你的例子似乎是基于我在 StackBlitz 中用它做的例子工作的,但是如果你看 errors.component.ts 你会看到它说 this.control.dirty || this.control.touched,这意味着您需要聚焦然后使用光标模糊输入,或者输入一个值然后退格删除它以进行所需的验证显示。

这是来自 docs and if you click them you can read up on their meaning. So for example dirtyFormControl 个属性的列表:

感动

get touched: boolean

A control is marked touched once the user has triggered a blur event on it.

get dirty: boolean

A control is dirty if the user has changed the value in the UI.

Note that programmatic changes to a control's value will not mark it dirty.

此外,通过查看您的代码,我建议您阅读 Angular 风格指南,并继续阅读 FormBuilder。在我制作的 StackBlitz 示例中,我将您的 FormGroup 示例切换为使用更简洁的 FormBuilder。最后,看起来您正在使用 jQuery 到 add/remove 类,但请查看 ngClass。在Angular中不需要jQuery,没有它你也可以做任何你想做的事情。

你可以试试这样的-

内部组件 (.ts) 文件 -

public loginForm: FormGroup = this.builder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.minLength(8), Validators.required]]

});

内部组件 (.html) 文件 -

<div class="l-form-row l-login-form__field-row">
      <label
        class="o-label l-form-label"
        for="email"
      >Enter your email</label>
      <div class="o-input-container">
        <input
          class="o-input"
          type="text"
          name="email"
          id="email"
          formControlName="email"
          placeholder="Email"
        ><div class="o-input-icon"></div>
      </div>
      <div
        class="o-input-error l-form-error"
        eValidationError="required"
        control="email"
      >Email is required</div>
      <div
        class="o-input-error l-form-error"
        eValidationError="email"
        control="email"
      >Email is invalid</div>
    </div>