2016-10-28 28 views
6

Formu geçersiz kılan form doğrulamaları eklemeye çalışıyorum. Doğrulama sadece uyarı olarak görünmelidir.Açısal 2 - Uyarılar/ipuçları için form doğrulaması

E.g. bir yaş doğrulama. 90 yaşından büyük bir yaş bir uyarı gösterir ve 120'den büyük bir yaş bir hatayı gösterir.

Bir formda iki FormGrup ile ve giriş alanında iki [formControl] ile denedim. Sadece ilk [formControl] kullanılır.

Bu tür bir doğrulama için Açısal form doğrulamasını kullanmak mümkün mü? Gitmenin yolu hangi yaklaşım?

cevap

10

Her zaman null döndüren özel doğrulayıcıyı oluşturarak yaptım. Ayrıca bu doğrulayıcı ek özellik warnings oluşturur. Ardından bu özelliği yalnızca görüntünüzden kontrol edin.

export interface AbstractControlWarn extends AbstractControl { warnings: any; } 

export function tooBigAgeWarning(c: AbstractControlWarn) { 
    if (!c.value) { return null; } 
    let val = +c.value; 
    c.warnings = val > 90 && val <= 120 ? { tooBigAge: {val} } : null; 
    return null; 
} 

export function impossibleAgeValidator(c: AbstractControl) { 
    if (tooBigAgeWarning(c) !== null) { return null; } 
    let val = +c.value; 
    return val > 120 ? { impossibleAge: {val} } : null; 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div [formGroup]="form"> 
     Age: <input formControlName="age"/> 
     <div *ngIf="age.errors?.required" [hidden]="age.pristine"> 
     Error! Age is required 
     </div> 
     <div *ngIf="age.errors?.impossibleAge" [hidden]="age.pristine"> 
     Error! Age is greater then 120 
     </div> 
     <div *ngIf="age.warnings?.tooBigAge" [hidden]="age.pristine"> 
     Warning! Age is greater then 90 
     </div> 
     <p><button type=button [disabled]="!form.valid">Send</button> 
    </div> 
    `, 
}) 
export class App { 
    age: FormControl; 
    constructor(private _fb: FormBuilder) { } 
    ngOnInit() { 
    this.form = this._fb.group({ 
     age: ['', [ 
     Validators.required, 
     tooBigAgeWarning, 
     impossibleAgeValidator]] 
    }) 
    this.age = this.form.get("age"); 
    } 
} 

Örnek: cevap için https://plnkr.co/edit/me0pHePkcM5xPQ7nzJwZ?p=preview

+0

İyi ve basit bir çözüm! Teşekkür ederim! – meleagros

0

Muhtemelen bunu nasıl yapardım.

Tamam

<form #form="ngForm" (ngSubmit)="save()"> 

    <input formControlName="controlName"> 

    <span *ngIf="form.pristine && form.controls.controlName.value > 90 && form.controls.controlName.value < 120"> 
    Warning: Age limit is high.. 
    </span> 

    <span *ngIf="form.pristine && form.controls.controlName.value > 120"> 
    Error: Age limit exceeded.. 
    </span> 

<form> 
+0

teşekkürler! İyi bir çözüm ancak form alanları ve doğrulamaları dinamik olarak oluşturduğumuz daha doğru bir çözüm kullanıyorum, böylece doğrulamaları kodlayamıyorum. – meleagros

1

onun size https://angular.io/docs/ts/latest/cookbook/form-validation.html

ama daha iyi zihnimde olabilir yardımcı olabilir benzer yolda belgeleri okuyabilir ima formu doğrulama için angular.io tarafından kolay olabilir.

İlk olarak, ortak bir işlev ve özellik içerdiği Form adlı bir soyut sınıf oluşturuyoruz.

import {FormGroup} from "@angular/forms"; 

export abstract class Form { 
    form: FormGroup; 

    protected abstract formErrors: Object; 

    protected abstract validationMessages: Object; 

    onValueChanged(data?: any) { 
     if (!this.form) { return; } 
     const form = this.form; 

     for (const field in this.formErrors) { 
      this.formErrors[field] = ''; 
      const control = form.get(field); 

      if (control && control.dirty && !control.valid) { 
       const messages = this.validationMessages[field]; 

       for (const key in control.errors) { 
        this.formErrors[field] = messages[key]; 
        break; 
       } 
      } 
     } 
    } 
} 

o zaman

import {Component, OnInit} from "@angular/core"; 
import {Form} from "./form"; 
import {Validators, FormBuilder} from "@angular/forms"; 


@Component({ 
    templateUrl: '...' 
}) 
export class LoginComponent extends Form implements OnInit { 

    protected formErrors = { 
     'email': '', 
     'password': '' 
    } 

    protected validationMessages = { 
     'email': { 
      'required': 'email required message', 
      'email': 'email validation message' 
     }, 
     'password': { 
      'required': 'password required message', 
      'minlength': 'password min length message', 
      'maxlength': 'password max length message', 
     } 
    } 

    constructor(private _fb: FormBuilder) { } 

    ngOnInit() { 
     this.buildForm(); 
    } 

    buildForm() { 
     this.form = this._fb.group({ 
      'email': ['', [ 
       Validators.required, 
       // emailValidator 
      ]], 
      'password': ['', [ 
       Validators.required, 
       Validators.minLength(8), 
       Validators.maxLength(30) 
      ]] 
     }); 

     this.form.valueChanges 
      .subscribe(data => this.onValueChanged(data)); 

     this.onValueChanged(); // 
    } 

} 

ilk biz (ana modülünde ReactiveFormModule içe unuttum yoktur) ve daha sonra reaktif formları için FormBuilder enjekte edilmelidir aşağıda gibi LoginComponent adında örneğin bir formu bileşeni oluşturmak için gereken [buildForm()] yönteminde, soyut sınıf Formundan miras alınan form özelliği üzerinde bir grup form oluşturuyoruz.

daha sonra, form değeri değişikliklerine ve [onValueChanged()] yöntemine değer verdiğimiz değer değişikliği için bir abone oluştururuz. [OnValueChanged()] yönteminde

yönteminde, korumalı validationMessages özelliğinden iletiyi almıyor ve formErrors özelliğinde göstermiyorsak, form alanlarının geçerli olup olmadığını kontrol ediyoruz.

ardından şablon hata bağlama varsa bu

<div class="col-md-4 col-md-offset-4"> 
    <form [formGroup]="form" novalidate> 


     <div class="form-group"> 
      <label class="control-label" for="email">email</label> 
      <input type="email" formControlName="email" id="email" class="form-control" required> 
      <div class="help help-block" *ngIf="formErrors.email"> 
       <p>{{ formErrors.email }}</p> 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label" for="password">password</label> 
      <input type="password" formControlName="password" id="password" class="form-control" required> 
      <div class="help help-block" *ngIf="formErrors.password"> 
       <p>{{ formErrors.password }}</p> 
      </div> 
     </div> 

     <div class="form-group"> 
      <button type="submit" class="btn btn-block btn-primary" [disabled]="!form.valid">login</button> 
     </div> 
    </form> 
</div> 

şablon alanını kontrol iç, çok kolay hata var ya da değil benzer olmalıdır.Eğer

<div class="form-group" [ngClass]="{'has-error': form.controls['email'].dirty && !form.controls['email'].valid, 'has-success': form.controls['email'].valid}"> 
    <label class="control-label" for="email">email</label> 
    <input type="email" 
      formControlName="email" 
      id="email" 
      class="form-control" 
      required> 
    <div class="help help-block" *ngIf="formErrors.email"> 
     <p>{{ formErrors.email }}</p> 
    </div> 
</div> 

aşağıda UPDATE gibi başka bir şeyi yapabileceği bootstrap için

: https://embed.plnkr.co/ExRUOtSrJV9VQfsRfkkJ/

:
Sana kesinlikle Wilder ölçek için onu geliştirebilir için çok basit ama neredeyse tamamen örnek oluşturma girişiminde

ama biraz bunun için tarif, gibi özel bir doğrulamaları oluşturabilir altında

import {ValidatorFn, AbstractControl} from '@angular/forms'; 

function isEmptyInputValue(value: any) { 
    return value == null || typeof value === 'string' && value.length === 0; 
} 

export class MQValidators { 

    static age(max: number, validatorName: string = 'age'): ValidatorFn { 
    return (control: AbstractControl): {[key: string]: any} => { 
     if (isEmptyInputValue(control.value)) return null; 

     const value = typeof control.value == 'number' ? control.value : parseInt(control.value); 

     if (isNaN(value)) return null; 

     if (value <= max) return null; 

     let result = {}; 
     result[validatorName] = {valid: false}; 

     return result; 
    } 
    } 

} 
buildForm() { 

    this.form = this._fb.group({ 
     'age': ['', [ 
      Validators.required, 
      Validators.pattern('[0-9]*'), 
      MQValidators.age(90, 'abnormalAge'), 
      MQValidators.age(120, 'incredibleAge') 
     ]] 
    }); 

    this.form.valueChanges 
     .subscribe(data => this.onValueChanged(data)); 

    this.onValueChanged(); 
} 

onValueChanged(data?: any): void { 
    if (!this.form) { return; } 
    const form = this.form; 

    for (const field in this.formErrors) { 
     this.formErrors[field] = ''; 
     const control = form.get(field); 

     if (control && control.dirty && !control.valid) { 
      const messages = this.validationMessages[field]; 

      for (const key in control.errors) { 
       this.formErrors[field] = messages[key]; 
      } 
     } 
    } 
} 

formErrors = { 
    age: '' 
} 

validationMessages = { 
    'age': { 
     'required': 'age is required.', 
     'pattern': 'age should be integer.', 
     'abnormalAge': 'age higher than 90 is abnormal !!!', 
     'incredibleAge': 'age higher than 120 is incredible !!!' 
    } 
} 

Umut ben yardımcı oldu: Eğer formComponent aşağıda gibi olmalıdır sizin örnekte olduğu gibi çok benzer doğrulama tayin nedeni

bu özel doğrulayıcı validatorName adında bir isteğe bağlı param, bu param olsun.

+0

Ayrıntılı gönderi için zaman ayırdığınız için teşekkür ederim, ancak bir alanın bir hata ürettiği ve formu geçersiz kıldığı ve diğerinin yalnızca bir uyarı gösterdiği iki farklı doğrulamaya sahip olduğunuz kısmı göremiyorum. Açıklamamın yaş alanıyla birlikte görün. Bir alana iki Validators.minLength eklemek istiyorum. – meleagros

+0

anladı, Sorununuz özel onaylar ile çözülebilir; Cevabı güncelleyeceğim. –

+0

Aşağıdaki çıktısı form.component.html {{form.controls.age.valid}} {{form.valid}} dosyanıza ekledim. Form ve alan da 91 geçersizdir. Buradaki fikir, formu geçersiz kılmaması, ancak yine de bir mesaj eklemesi gerektiği yönündeki özel doğrulamayı anlatmaktır. – meleagros