2016-06-07 3 views
1


Ich bin neu in Angular2.
Ich versuche, JQuery ui Datepicker in angular2 zu implementieren.
JQuery UI Datepicker in angular2

Ich habe eine DatePicker-Direktive geschrieben, dort habe ich Datepicker aktiviert. Hier kann ich das Datum auswählen, aber es ist schwierig, das ausgewählte Datum an die Elternkomponente zu senden.

um dies zu überwinden Ich habe ein Objekt auf Fenster-Objekt erstellt und übergeben Komponente Verweis auf das Objekt. Von dort rufe ich die Komponentenfunktion auf.

Ich denke, das ist keine Best Practice zu tun.

Kann mir jemand auf die richtige Weise helfen.

import { Directive, ElementRef, Input, NgZone,HostListener,Output,EventEmitter } from '@angular/core'; 
    declare var $:any; 
    @Directive({ 
     selector: '[uiDatePicker]', 
    }) 
    export class UiDatePickerDirective { 
     @Input('uiDatePicker') setDate: string; 
     @Output() onSelectDate = new EventEmitter(); 
     private el: HTMLElement; 
     constructor(el: ElementRef,public zone:NgZone) { 
     this.el = el.nativeElement; 

     window.angularComponentRef = { 
      zone: this.zone, 
      component: this 
     }; 
     } 

     doEmitDate(dateText:string){ 
      this.onSelectDate.emit(dateText); 
     } 
     ngOnInit() { 
     $(this.el).datepicker({ 
     onSelect: function(dateText:string) { 
      window.angularComponentRef.component.doEmitDate(dateText); 
     } 
     }); 
     } 
} 

Hier ich nicht window.angularComponentRef.component Objekt verwenden möchten. Da es nur die Referenz im globalen Objekt speichert. Das ist nicht gut für eine Anwendung.

Antwort

1

Für alle Absichten und Zwecke können Sie die var self = this Ideologie und Verschlüsse verwenden, um einen Verweis auf die Komponente beizubehalten.

Wenn Sie keine Vorverarbeitung im onSelect Rückruf durchführen, können Sie die Dinge weiter vereinfachen, indem Sie eine gebundene doEmitDate Funktion als onSelect Handler übergeben.

import { Directive, ElementRef, Input, NgZone,HostListener,Output,EventEmitter } from '@angular/core'; 
declare var $:any; 

@Directive({ 
    selector: '[uiDatePicker]', 
}) 
export class UiDatePickerDirective { 
    @Input('uiDatePicker') setDate: string; 
    @Output() onSelectDate = new EventEmitter(); 
    private el: HTMLElement; 

    constructor(el: ElementRef, public zone: NgZone) { 
    this.el = el.nativeElement; 
    } 

    doEmitDate(dateText:string){ 
    this.onSelectDate.emit(dateText); 
    } 

    ngOnInit() { 
    const component = this; 
    $(this.el).datepicker({ 
     onSelect: function(dateText: string) { 
     component.doEmitDate(dateText); 
     } 
    }); 

    // Or if you're not doing anything else in the onSelect callback 
    $(this.el).datepicker({ 
     onSelect: this.doEmitDate.bind(this) 
    }); 
    } 
} 
+0

Ich denke, es ist eine einfache Antwort. Kannst du mir irgendwelche anderen Möglichkeiten vorschlagen, dasselbe auf eckige Weise zu tun? –

+0

Es gibt keine angularspezifische Methode, um so etwas zu tun. Das 'nativeElement' mit' ElementRef' zu erfassen, ist die einzige Sache, die man beachten sollte, wenn man in diesen Situationen Elemente an externe Bibliotheken übergibt, und genau das macht man. Manchmal ist die einfache Antwort die richtige Antwort, keine Notwendigkeit zu komplizieren. – hotforfeature

+0

danke für Ihre Bestätigung. :) –

2

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(() => UiDatePickerDirective), 
 
    multi: true 
 
}; 
 

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

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

 
    constructor(private el: ElementRef) { 
 
    } 
 

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

 

 
    public onChange: any = (_: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; 
 
     $(this.el.nativeElement).datepicker("setDate", this.innerValue); 
 
    } 
 

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

 
    registerOnTouched(fn: any): void { 
 
     this.onTouched = fn; 
 
    } 
 
}
<input type="text" uiDatePicker [(ngModel)]="note.ValidTo"/>

Dies ist eine modifizierte Version von here.

+0

Ich habe diese Lösung in meiner Anwendung implementiert. Ein Problem, mit dem ich konfrontiert bin, ist, wie man ein Datum pragmatisch in ein Textfeld setzt, das diese Direktive hat. Ich verwende Form Builder, um Daten festzulegen. –

+0

Aktualisieren Sie die note.ValidTo Variable in eckigen? – kravits88

+0

Ich habe keine Ahnung davon. Wo ist diese Variable verfügbar? Ich habe versucht, es zu googeln, aber kein Glück! –