表单验证 Angular 4 [英] Form Validation Angular 4

查看:25
本文介绍了表单验证 Angular 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

然而,当我实施它并提交我的表单时,屏幕上的任何地方都没有显示错误.您将在下面找到我能想到的所有相关代码.我正在寻找如何让错误显示在屏幕上.我对 Angular 4 还很陌生,所以任何帮助将不胜感激.

pages.module.ts

导入...从@angular/forms"导入 { FormsModule, ReactiveFormsModule };进口 ...从'./register/register.component'导入{注册组件};进口 ...import { ErrorsComponent } from '../errors.component';@NgModule({进口:[通用模块,RouterModule.forChild(PagesRoutes),表单模块,响应式表单模块],声明: [登录组件,注册组件,锁组件,错误组件]})导出类 PagesModule {}

register.component.ts

导入...从@angular/forms"导入 {FormGroup、FormBuilder、Validators、FormControl、NgForm};进口 ...import { CustomValidators } from "../../validators/custom-validator.directive";声明 var $:any;@成分({moduleId:module.id,选择器:'注册-cmp',templateUrl: './register.component.html'})导出类 RegisterComponent 实现 OnInit{注册表格:表格组;测试:日期=新日期();加载 = 假;错误 = '';构造函数(私有表单:FormBuilder,专用路由器:路由器,私有认证服务:AuthenticationService){this.registerForm = new FormGroup ({'用户名':new FormControl('', Validators.required),'email': new FormControl('', [Validators.required, CustomValidators.validEmail]),'first_name': new FormControl('', Validators.required),'last_name': new FormControl('', Validators.required),'密码': new FormControl('', Validators.required),'confirmPassword': new FormControl('', Validators.required)});}checkFullPageBackgroundImage(){var $page = $('.full-page');var image_src = $page.data('image');如果(image_src !== 未定义){var image_container = '<div class="full-page-background" style="background-image: url(' + image_src + ') "/>'$page.append(image_container);}};ngOnInit() {this.checkFullPageBackgroundImage();设置超时(功能(){//1000 毫秒后,我们将动画类添加到登录/注册卡$('.card').removeClass('card-hidden');}, 700)}注册(注册表格:NgForm){console.log(this.registerForm.value);}}

register.component.html

<div class="card card-plain"><div class="内容"><div class="form-group"><input type="text" placeholder="你的名字" class="form-control" formControlName="first_name"><errors [control]="registerForm.controls.first_name"></errors>

<div class="form-group"><input type="text" placeholder="您的姓氏" class="form-control" formControlName="last_name"><errors [control]="registerForm.controls.last_name"></errors>

<div class="form-group"><input type="text" placeholder="Username" class="form-control" formControlName="username"><errors [control]="registerForm.controls.username"></errors>

<div class="form-group"><input type="email" placeholder="Enter email" class="form-control" formControlName="email"><errors [control]="registerForm.controls.email"></errors>

<div class="form-group"><input type="password" placeholder="Password" class="form-control" formControlName="password"><errors [control]="registerForm.controls.password"></errors>

<div class="form-group"><input type="password" placeholder="密码确认" class="form-control" formControlName="confirmPassword"><errors [control]="registerForm.controls.confirmPassword"></errors>

<div class="footer text-center"><button [disabled]="loading" type="submit" class="btn btn-fill btn-neutral btn-wd">创建账户</button><i *ngIf="loading" class="fa fa-spinner fa-spin fa-fw"></i>

<errors [control]="registerForm"></errors>

</表单>

errors.component.ts

import { Component, Input } from '@angular/core';从@angular/forms"导入 { AbstractControlDirective, AbstractControl };@成分({选择器:'错误',模板:`<ul *ngIf="showErrors()"><li class="help-box text-warning" *ngFor="let error of errors()">{{error}}</li>`,})导出类 ErrorsComponent {私有静态只读 errorMessages = {'必需':() =>'此字段是必需的','minlength': (params) =>'最小字符数为' + params.requiredLength,'maxlength': (params) =>'允许的最大字符数为 ' + params.requiredLength,'模式':(参数)=>'所需的模式是:' + params.requiredPattern,'年龄':(参数)=>params.message,'validEmail': (params) =>参数.message};@输入()私有控制:AbstractControlDirective |抽象控件;显示错误():布尔{返回 this.control &&this.control.errors &&(this.control.dirty || this.control.touched);}错误():字符串[] {返回 Object.keys(this.control.errors).map(field => this.getMessage(field, this.control.errors[field]));}私人 getMessage(类型:字符串,参数:任何){返回 ErrorsComponent.errorMessages[type](params);}}

解决方案

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

这是来自 docsFormControl 属性列表如果您单击它们,您可以阅读它们的含义.例如 dirty:

感动

<块引用>

接触:布尔值

一旦用户在控件上触发了模糊事件,控件就会被标记为已触摸.

<块引用>

变脏:布尔值

如果用户更改了 UI 中的值,则控件是脏的.

请注意,对控件值的编程更改不会标记它脏.

此外,通过查看您的代码,我建议您也阅读 Angular 风格指南阅读FormBuilder.在我制作的 StackBlitz 示例中我将您的 FormGroup 示例切换为使用 FormBuilder,它更简洁.最后,看起来您正在使用 jQuery 添加/删除类,而是查看 ngClass.在 Angular 中你不需要 jQuery,你可以在没有它的情况下做你需要的一切.

So, I was attempting to use the following example: https://github.com/agiratech/angular4-reactive-form-exercise2/

However, when I implement it, and submit my form, no errors show anywhere on the screen. Below you will find all associated code that I can think of that relates. I'm looking for how to get the errors to show on the screen. I'm fairly new to Angular 4, so any help would be appreciated.

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);
  }

}

解决方案

Your example seems to work based on an example I made from it in StackBlitz, but if you look at errors.component.ts you'll see that it says this.control.dirty || this.control.touched, which means you need to focus and then blur the input using your cursor, or enter a value and then backspace removing it to make the required validation display.

This is a list of FormControl properties from the docs and if you click them you can read up on their meaning. So for example dirty:

Touched

get touched: boolean

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

Dirty

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.

Also, from looking at your code I'd suggest reading the Angular Style Guide, as well as reading up on the FormBuilder. In the StackBlitz example I made I switched your FormGroup example to use FormBuilder, which is more succinct. Finally, it looks like you're using jQuery to add/remove classes, but instead, have a look at ngClass. You don't need jQuery in Angular, you can do everything you need without it.

这篇关于表单验证 Angular 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆