如何在 Angular 2 中添加表单验证模式?

Posted

技术标签:

【中文标题】如何在 Angular 2 中添加表单验证模式?【英文标题】:How to add form validation pattern in Angular 2? 【发布时间】:2016-04-06 04:19:49 【问题描述】:

我有一个简单的表单,需要验证输入的开头和结尾是否不是空格。

html5 中,我会这样做:

<input type="text" pattern="^(?!\s|.*\s$).*$">

新的 Angular 2 ngControl 指令中验证模式的正确属性是什么?官方 Beta API 仍然缺乏关于此问题的文档。

【问题讨论】:

目前没有直接的方法可以做到这一点。您可以编写自己的自定义验证器,直到这个 pull request 登陆(如果有的话)。 这里是一个例子,如果你沿着这条路走,如何进行自定义验证syntaxsuccess.com/viewarticle/… 【参考方案1】:

现在,您不需要使用FormBuilder 和所有这些复杂的验证角度的东西。我从中提供了更多详细信息(Angular 2.0.8 - 3march2016): https://github.com/angular/angular/commit/38cb526

回购示例:

<input [ngControl]="fullName" pattern="[a-zA-Z ]*">

我对其进行了测试,它可以工作:) - 这是我的代码:

<form (ngSubmit)="onSubmit(room)" #roomForm='ngForm'  >
...
<input 
  id='room-capacity' 
  type="text" 
  class="form-control" 
  [(ngModel)]='room.capacity' 
  ngControl="capacity" 
  required
  pattern="[0-9]+" 
  #capacity='ngForm'>

替代方法(2017 年 6 月更新)

验证仅在服务器端。如果出现问题,则服务器返回错误代码,例如 HTTP 400 并在响应正文中跟随 json 对象(例如):

this.err =  
    "capacity" : "too_small"
    "filed_name" : "error_name", 
    "field2_name" : "other_error_name",
    ... 

在 html 模板中,我使用单独的标签(div/span/small 等)

<input [(ngModel)]='room.capacity' ...>
<small *ngIf="err.capacity" ...> translate(err.capacity) </small>

如果在“容量”中出错,则带有 msg 翻译的标签将可见。这种方法有以下优点:

很简单 避免在前端重复后端验证代码(对于正则表达式验证,这可以防止ReDoS 攻击或使ReDoS 攻击复杂化) 控制错误的显示方式(例如&lt;small&gt;标签) 后端返回error_name,很容易在前端翻译成正确的语言

当然,如果前端需要验证,有时我会例外(例如,注册时的retypePassword 字段永远不会发送到服务器)。

【讨论】:

我只是检查(并测试)Chris Snowden 在之前的回答中提到的变更日志。他给出了主要的暗示。 将模式转换为这种新类型的公式是什么?例如: ng-pattern="/^(\+\911,2)\d10$/" @VahidAlimohamadi 我不明白这个问题,你能不能重复一遍? @VahidAlimohamadi 在开头删除“/”并在您的正则表达式末尾添加广告。所以它应该是你的情况: pattern="^(\+\911,2)\d10$" (可能你还必须在你的正则表达式中删除或更改反斜杠'\') @zennin 你可以试试这个(但我不检查):***.com/questions/10361460/…【参考方案2】:

自版本 2.0.0-beta.8 (2016-03-02) 起,Angular 现在包含一个 Validators.pattern 正则表达式验证器。

见CHANGELOG

【讨论】:

很好的答案 - 你可以节省五月天! :) 你能帮我解决这个问题吗***.com/questions/52091334/…@ChrisSnowden【参考方案3】:

您可以使用 FormBuilder 构建您的表单,因为它让您可以更灵活地配置表单。

export class MyComp 
  form: ControlGroup;

  constructor(@Inject()fb: FormBuilder)   
    this.form = fb.group(  
      foo: ['', MyValidators.regex(/^(?!\s|.*\s$).*$/)]  
    );  
  

然后在你的模板中:

<input type="text" ngControl="foo" />
<div *ngIf="!form.foo.valid">Please correct foo entry !</div> 

您还可以自定义 ng-invalid CSS 类。

由于正则表达式实际上没有验证器,因此您必须自己编写。这是一个简单的函数,在输入中接受一个控件,如果有效则返回 null,如果无效则返回 StringMap。

export class MyValidators 
  static regex(pattern: string): Function 
    return (control: Control): [key: string]: any => 
      return control.value.match(pattern) ? null : pattern: true;
    ;
  

希望对你有帮助。

【讨论】:

Angular2 有自己的模式验证器。来源:angular.io/docs/ts/latest/api/forms/index/Validators-class.html 准确。但在一年前写下回复时,情况并非如此。【参考方案4】:

自定义验证一步一步

HTML模板

  <form [ngFormModel]="demoForm">
  <input  
  name="NotAllowSpecialCharacters"    
  type="text"                      
  #demo="ngForm"
  [ngFormControl] ="demoForm.controls['spec']"
  >

 <div class='error' *ngIf="demo.control.touched">
   <div *ngIf="demo.control.hasError('required')"> field  is required.</div>
   <div *ngIf="demo.control.hasError('invalidChar')">Special Characters are not Allowed</div>
 </div>
  </form>

组件 App.ts

import Control, ControlGroup, FormBuilder, Validators, NgForm, NgClass from 'angular2/common';
import CustomValidator from '../../yourServices/validatorService';

下课 定义

 demoForm: ControlGroup;
constructor( @Inject(FormBuilder) private Fb: FormBuilder ) 
    this.demoForm = Fb.group(
       spec: new Control('', Validators.compose([Validators.required,   CustomValidator.specialCharValidator])),
      )

../../yourServices/validatorService.ts

export class CustomValidator 
    static specialCharValidator(control: Control):  [key: string]: any  
   if (control.value) 
       if (!control.value.match(/[-!$%^&*()_+|~=`\[\]:";#@'<>?,.\/]/))             
           return null;
       
       else             
           return  'invalidChar': true ;
       
   

 

 

【讨论】:

【参考方案5】:

我使用 Angular 4.0.1 的解决方案:只显示所需 CVC 输入的 UI - 其中 CVC 必须是 3 位数字:

    <form #paymentCardForm="ngForm">         
...
        <md-input-container align="start">
            <input #cvc2="ngModel" mdInput type="text" id="cvc2" name="cvc2" minlength="3" maxlength="3" placeholder="CVC" [(ngModel)]="paymentCard.cvc2" [disabled]="isBusy" pattern="\d3" required />
            <md-hint *ngIf="cvc2.errors && (cvc2.touched || submitted)" class="validation-result">
                <span [hidden]="!cvc2.errors.required && cvc2.dirty">
                    CVC is required.
                </span>
                <span [hidden]="!cvc2.errors.minlength && !cvc2.errors.maxlength && !cvc2.errors.pattern">
                    CVC must be 3 numbers.
                </span>
            </md-hint>
        </md-input-container>
...
<button type="submit" md-raised-button color="primary" (click)="confirm($event, paymentCardForm.value)" [disabled]="isBusy || !paymentCardForm.valid">Confirm</button>
</form>

【讨论】:

【参考方案6】:

无需验证模式,您可以使用这些模块轻松修剪开始和结束空格。试试这个。

https://www.npmjs.com/package/ngx-trim-directive https://www.npmjs.com/package/ng2-trim-directive

谢谢。

【讨论】:

实际上,对于两者来说,如果值内部(中间)允许有空间,trim="blur" 就可以解决问题。

以上是关于如何在 Angular 2 中添加表单验证模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ANGULAR 2 中提交表单时重置表单验证

如何使用响应式表单将验证器添加到表单控件以从角度材料进行匹配输入

Angular2获取表单控件的现有验证器

如何在 Angular Js 中使用名称或 id 属性验证表单

如何使用 Angular 2 在单个 ts 文件中编写 2 个表单验证?

Angular 表单:如何动态添加/删除子表单组件