2017-01-26 1 views
1

Мне нужно инициировать проверку изнутри директивы валидатора.Angular2 - доступ к экземпляру AbstractControl в директиве проверки

Вот директива, которую я имею. Он работает так, как ожидалось. Однако я хочу, чтобы он запускал процесс проверки при изменении функции валидатора. То есть когда изменяется его входная переменная maxDate.

Как я мог это сделать?

Если бы я мог получить доступ к экземпляру AbstractControl в конструкторе, я мог бы легко сделать это. Однако я не могу придумать, как это сделать.

import { AbstractControl, FormGroup, ValidatorFn, Validator, NG_VALIDATORS, Validators } from '@angular/forms'; 
import { Directive, Input, OnChanges, SimpleChanges, EventEmitter } from '@angular/core'; 


function parseDate(date: string):any { 
    var pattern = /(\d{2})-(\d{2})-(\d{4})/; 
    if (date) { 
    var replaced = date.search(pattern) >= 0;  
    return replaced ? new Date(date.replace(pattern,'$3-$1-$2')) : null; 
    } 

    return date; 
} 


export function maxDateValidator(maxDateObj): ValidatorFn { 
    return (control:AbstractControl): {[key: string]: any} => {  
    const val = control.value; 

    let date = parseDate(val); 
    let maxDate = parseDate(maxDateObj.max);  

    if (date && maxDate && date > maxDate) { 
     return { 
     maxDateExceeded: true 
     }; 
    } 
    return null; 
    }; 
} 

...

@Directive({ 
    selector: '[maxDate]', 
    providers: [{provide: NG_VALIDATORS, useExisting: maxDateDirective, multi: true}] 
}) 
export class maxDateDirective implements Validator, OnChanges { 
    @Input() maxDate: string; 

    private valFn = Validators.nullValidator; 

    constructor() { } 

    ngOnChanges(changes: SimpleChanges): void { 
    const change = changes['maxDate']; 
    if (change) { 
     const val: string = change.currentValue;  
     this.valFn = maxDateValidator(val); 
    } 
    else { 
     this.valFn = Validators.nullValidator; 
    } 
    //This is where I want to trigger the validation again. 
    } 

    validate(control): {[key: string]: any} { 
    return this.valFn(control); 
    } 
} 

Использование:

<input type="text" [(ngModel)]="deathDateVal"> 

    <input class="form-control"   
      type="text" 
      tabindex="1" 
      [maxDate]="deathDateVal" 
      name="will_date" 
      [textMask]="{pipe: datePipe, mask: dateMask, keepCharPositions: true}" 
      ngModel 
      #willDate="ngModel"> 
+0

Ваш код, кажется, в порядке, в чем проблема с ним? – AngularChef

+0

Я хочу повторить проверку при изменении параметров валидации. I.e 'maxDate' –

+0

Извините, я не понимаю. 'ngOnChanges' вызывается всякий раз, когда любой вход изменяется, поэтому всякий раз, когда изменяется maxDate. Ваш код должен работать. – AngularChef

ответ

1

Ну ...

так ...

Вот что я просто придумать:

@Directive({ 
    selector: '[maxDate]', 
    providers: [{provide: NG_VALIDATORS, useExisting: maxDateDirective, multi: true}] 
}) 
export class maxDateDirective implements Validator, OnChanges { 
    @Input() maxDate: string; 

    private valFn = Validators.nullValidator; 
    private control:AbstractControl; 

    constructor() { } 

    ngOnChanges(changes: SimpleChanges): void { 
    const change = changes['maxDate']; 
    if (change) { 
     const val: string = change.currentValue;  
     this.valFn = maxDateValidator(val); 
    } 
    else { 
     this.valFn = Validators.nullValidator; 
    } 

    if (this.control) { 
     this.control.updateValueAndValidity(this.control); 
    } 
    } 

    validate(_control:AbstractControl): {[key: string]: any} { 
    this.control = _control; 
    return this.valFn(_control); 
    } 
} 

Это работает. Validate вызывается при инициализации, поэтому я просто сохраняю его параметр. Это чертовски некрасиво, но оно работает.

Приветствия всем, кто пытается это решить!

Смежные вопросы