2016-10-04 91 views
12

thoughtgram.io,目前支持的驗證程序是:最小/最大驗證在角2最終

  • 需要
  • MINLENGTH個
  • 最大長度
  • 模式

因此,考慮到以下代碼(plunkr here):

@Component({ 
    selector: 'my-app', 
    template: ` 

    <form #formRef="ngForm"> 
    <input type="number" [(ngModel)]="firstValue" name="firstValue" min="0" required/> 
    <input type="text" [(ngModel)]="secondValue" maxlength="5" name="secondValue" required/> 
    <button type="submit"> Submit </button> 
    </form> 

    FORM: {{formRef.form | json }} 
` 
}) 
export class AppComponent { 
    firstValue = -22; 
    secondValue = "eyy macarena!"; 
} 

雖然minlength支持,min="0"由角驗證忽略:

enter image description here

enter image description here

因此,爲了使窗體導致錯誤時firstValue ngModel < 0,我需要建立一個自定義驗證器?

+0

'FirstValue <0',和' David

+0

是的,你需要。在這裏檢查源代碼:https://github.com/angular/angular/blob/master/modules/%40angular/forms/src/directives/validators.ts只有那些由thetram文章提到的4個驗證器才支持OOTB。 –

回答

22

要在number適用min/max validation則需要當前創建Custom Validator

Validators類只有幾驗證,即

  • 需要
  • requiredTrue
  • 最小長度
  • 的maxlength
  • 圖案
  • nullValidator
  • 構成
  • composeAsync

驗證:這裏被淡化了我的電話號碼驗證的版本,你可以改善它,只要你喜歡

static number(prms = {}): ValidatorFn { 
    return (control: FormControl): {[key: string]: string} => { 
     if(isPresent(Validators.required(control))) { 
     return null; 
     } 

     let val: number = control.value; 

     if(isNaN(val) || /\D/.test(val.toString())) { 

     return {"number": true}; 
     } else if(!isNaN(prms.min) && !isNaN(prms.max)) { 

     return val < prms.min || val > prms.max ? {"number": true} : null; 
     } else if(!isNaN(prms.min)) { 

     return val < prms.min ? {"number": true} : null; 
     } else if(!isNaN(prms.max)) { 

     return val > prms.max ? {"number": true} : null; 
     } else { 

     return null; 
     } 
    }; 
    } 

用法:

// check for valid number 
var numberControl = new FormControl("", [Validators.required, CustomValidators.number()]) 

// check for valid number and min value 
var numberControl = new FormControl("", CustomValidators.number({min: 0})) 

// check for valid number and max value 
var numberControl = new FormControl("", CustomValidators.number({max: 20})) 

// check for valid number and value range ie: [0-20] 
var numberControl = new FormControl("", CustomValidators.number({min: 0, max: 20})) 
+16

爲什麼不能角度2只支持輸入的內置'min' /'max'屬性?這是非常不直觀的 – Blauhirn

+7

@Blauhirn不知道,編寫驗證器的人可能中途無聊:) – David

+11

Angular 4現在支持最小/最大驗證器。 https://angular.io/api/forms/Validators – Olezt

-2

在您的代碼中,您使用的是min而不是minlength。請注意,這不會驗證數字是否大於0而是其長度。

+1

問題是關於min2是如何被NG2驗證支持的,而min不是,如果這是故意的,開箱即用的事情 - 或者我缺少一些NG知識。我知道最小和最小長度之間的差異:P – David

2

我發現這是一個解決方案。創建一個自定義的驗證如下

minMax(control: FormControl) { 
     return parseInt(control.value) > 0 && parseInt(control.value) <=5 ? null : { 
     minMax: true 
     } 
    } 

,並在構造函數中包括下面的代碼

this.customForm= _builder.group({ 
        'number': [null, Validators.compose([Validators.required, this.minMax])], 
       }); 

其中customForm是FormGroup和_builder是FormBuilder。

7

據我所知,是現在實施,檢查https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts

這是部分實現你在找什麼:

export class Validators { 
    /** 
    * Validator that requires controls to have a value greater than a number. 
    */ 
    static min(min: number): ValidatorFn { 
    return (control: AbstractControl): ValidationErrors | null => { 
     if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) { 
     return null; // don't validate empty values to allow optional controls 
     } 
     const value = parseFloat(control.value); 
     // Controls with NaN values after parsing should be treated as not having a 
     // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min 
     return !isNaN(value) && value < min ? {'min': {'min': min, 'actual': control.value}} : null; 
    }; 
    } 

    /** 
    * Validator that requires controls to have a value less than a number. 
    */ 
    static max(max: number): ValidatorFn { 
    return (control: AbstractControl): ValidationErrors | null => { 
     if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) { 
     return null; // don't validate empty values to allow optional controls 
     } 
     const value = parseFloat(control.value); 
     // Controls with NaN values after parsing should be treated as not having a 
     // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max 
     return !isNaN(value) && value > max ? {'max': {'max': max, 'actual': control.value}} : null; 
    }; 
    } 
5
  1. 切換到使用活性形式,而不是模板形式(他們只是更好),否則第5步會略有不同。
  2. 創建服務NumberValidatorsService並添加驗證功能:

    import { Injectable } from '@angular/core'; 
    import { FormControl, ValidatorFn } from '@angular/forms'; 
    
    @Injectable() 
    export class NumberValidatorsService { 
    
    constructor() { } 
    
        static max(max: number): ValidatorFn { 
    return (control: FormControl): { [key: string]: boolean } | null => { 
    
        let val: number = control.value; 
    
        if (control.pristine || control.pristine) { 
        return null; 
        } 
        if (val <= max) { 
        return null; 
        } 
        return { 'max': true }; 
        } 
    } 
    
    static min(min: number): ValidatorFn { 
    return (control: FormControl): { [key: string]: boolean } | null => { 
    
        let val: number = control.value; 
    
        if (control.pristine || control.pristine) { 
        return null; 
        } 
        if (val >= min) { 
        return null; 
        } 
        return { 'min': true }; 
        } 
    } 
    
    } 
    
  3. 進口服務到模塊。

  4. 添加包括組件聲明它被使用:

    import { NumberValidatorsService } from "app/common/number-validators.service"; 
    
  5. 添加驗證,形成建設者:

    this.myForm = this.fb.group({ 
         numberInputName: [0, [Validators.required, NumberValidatorsService.max(100), NumberValidatorsService.min(0)]], 
        }); 
    
  6. 在模板中,可以顯示錯誤如下:

    <span *ngIf="myForm.get('numberInputName').errors.max"> 
         numberInputName cannot be more than 100. 
        </span> 
    
1

通過創建實現接口的指令,您可以輕鬆實現自己的驗證(模板驅動)。

import { Directive, Input, forwardRef } from '@angular/core' 
import { NG_VALIDATORS, Validator, AbstractControl, Validators } from '@angular/forms' 

@Directive({ 
    selector: '[min]', 
    providers: [{ provide: NG_VALIDATORS, useExisting: MinDirective, multi: true }] 
}) 
export class MinDirective implements Validator { 

    @Input() min: number; 

    validate(control: AbstractControl): { [key: string]: any } { 

    return Validators.min(this.min)(control) 

    // or you can write your own validation e.g. 
    // return control.value < this.min ? { min:{ invalid: true, actual: control.value }} : null 



    } 

} 
+0

這將是更有幫助,如果你解釋像上面的答案https://stackoverflow.com/a/44722596/3898339 –