2016-11-19 41 views
5

Próbuję stworzyć własną dyrektywę Angular 2 dla Jquery UI Datepicker. Widziałem różne podejścia w Internecie oraz w SO, ale nikt nie osiągnął celu, który chcę osiągnąć. Więc to jest kod, który mam do tej pory:Angular 2 Dyrektywa wdrażająca ControlValueAccessor nie aktualizuje właściwości "dotkniętych" przy zmianie

import {Directive, ElementRef, Input, forwardRef} from '@angular/core'; 
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms"; 

declare var $:any; 

@Directive({ 
    selector: '[date-picker]', 
    providers: [{ 
    provide: NG_VALUE_ACCESSOR,useExisting: 
     forwardRef(() => DatePickerDirective), 
    multi: true 
    }] 
}) 
export class DatePickerDirective implements ControlValueAccessor { 
    private value: string; 

    @Input('changeMonth') changeMonth:boolean = true; 
    @Input('changeYear') changeYear:boolean = true; 

    constructor(private el: ElementRef) { 

    } 

    ngAfterViewInit(){ 
    $(this.el.nativeElement).datepicker({ 
     changeMonth: this.changeMonth, 
     yearRange: "1:100", 
     changeYear: this.changeYear 
    }).on('change', e => this.onChange(e.target.value)); 
    } 

    onChange: Function =() => {}; 

    onTouched: Function =() => {}; 

    writeValue(val: string) : void { 
    this.value = val; 
    } 

    registerOnChange(fn: Function): void { 
    this.onChange = fn; 
    } 

    registerOnTouched(fn: Function): void { 
    this.onTouched = fn; 
    } 
} 

Co się dzieje jest to, że nawet kiedy wybrać datę (kompletacji) lub wpisać go bezpośrednio w polu tekstowym, nie jest aktualizacją „dotknął” mienia.

Czy masz jakieś pomysły na jego rozwiązanie?

+0

Jego już realizować w dwóch miejscach NG2-bootstrap & ng-bootstrap, byś nic przeciwko aby przejrzeć bootstrap wersji angular2, możesz sprawdzić [tutaj] (https://ng-bootstrap.github.io/#/components/datepicker)? –

+0

@PankajParkar Tak! Właściwie widziałem to już wcześniej i nie jest to dokładnie to, czego potrzebuję z różnych powodów. Muszę dostosować różne rzeczy. Pierwszy krok (i wyzwanie) to ten, o którym wspomniałem wcześniej. –

Odpowiedz

5

Dla tych, którzy w końcu mają ten sam problem, ja wymyśliliśmy sposób zarządzać, jak można poniżej:

import {Directive, ElementRef, Input, forwardRef} from '@angular/core'; 
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms"; 

declare var $:any; 

export const CUSTOM_INPUT_DATE_PICKER_CONTROL_VALUE_ACCESSOR: any = { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => DatePickerDirective), 
    multi: true 
}; 

@Directive({ 
    selector: '[date-picker]', 
    host: {'(blur)': 'onTouched($event)'}, 
    providers: [CUSTOM_INPUT_DATE_PICKER_CONTROL_VALUE_ACCESSOR] 
}) 
export class DatePickerDirective implements ControlValueAccessor { 
    private innerValue: string; 

    @Input('changeMonth') changeMonth:boolean = true; 
    @Input('changeYear') changeYear:boolean = true; 

    constructor(private el: ElementRef) { 
    $(this.el.nativeElement).datepicker({ 
     changeMonth: true, 
     changeYear: true, 
     dateFormat: 'dd/mm/yy' 
    }).on('change', e => this.onChange(e.target.value)); 
    } 

    public onChange: any = (_) => { /*Empty*/ } 
    public onTouched: any =() => { /*Empty*/ } 

    get value(): any { 
    return this.innerValue; 
    }; 

    //set accessor including call the onchange callback 
    set value(v: any) { 
    if (v !== this.innerValue) { 
     this.innerValue = v; 
     this.onChange(v); 
    } 
    } 

    writeValue(val: string) : void { 
    this.innerValue = val; 
    } 

    registerOnChange(fn: any): void { 
    this.onChange = fn; 
    } 

    registerOnTouched(fn: any): void { 
    this.onTouched = fn; 
    } 
} 
+0

Dzięki za odpowiedź na własne pytanie. Pomogło mi! – kravits88