Reputation: 1145
I'm wrapping jquery's datepicker for use in angular2 and am running into a situation where the class of a member variable is changing somehow. For reference, I'm a beginner here.
First, here is the code (based on the example from http://www.radzen.com/blog/jquery-plugins-and-angular/ ):
import { forwardRef, ViewChild, Input, Output, EventEmitter, ElementRef, AfterViewInit, OnDestroy, Component} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import * as $ from "jquery";
import 'jqueryui';
const DATE_PICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
};
@Component({
selector: 'qnet-datepicker',
template: `<input #input type="text">`,
providers: [DATE_PICKER_VALUE_ACCESSOR]
})
export class DatePickerComponent implements AfterViewInit, ControlValueAccessor, OnDestroy {
private onTouched = () => {};
private onChange: (date: Date) => void = () => {};
@Input() date: Date;
@Input() options: any = {};
@Output() dateChange = new EventEmitter();
@ViewChild('input') input: ElementRef;
constructor() {
this.date = new Date();
}
writeValue(date: Date) {
if(!date) {
return;
}
this.date = date;
$(this.input.nativeElement).datepicker('setDate', this.date)
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
ngAfterViewInit() {
$(this.input.nativeElement).datepicker(Object.assign({}, this.options, {
onSelect: (dateStr: string) => {
// this.date = $(this.input.nativeElement).datepicker('getDate');
// this.onChange(this.date);
this.onTouched();
this.dateChange.next(this.date);
}
}))
console.log('date is ' + this.date)
$(this.input.nativeElement).datepicker('setDate', this.date)
}
ngOnDestroy() {
$(this.input.nativeElement).datepicker('destroy');
}
}
In the constructor the type of this.date is 'Date' but by time I get to ngAfterViewInit the type has somehow changed to 'DatePickerComponent'. How can this happen?
edit
Additional info: the html using the datepicker was something like
<qnet-datepicker #startDate [date]="startDate" (dateChange)="updateStart(startDate.date, startTime.value)"></qnet-datepicker>
As ahmed describes in his answer, this ended up accidentally binding the member variable to the element instead of the date. Part of my confusion was relying on typescript being strongly typed, but hookups between html and logic is done via javascript so no longer has the strongly type'd property.
Upvotes: 0
Views: 150
Reputation: 9753
After a look at the github repo, the issue is this:
daterangepicker.component.ts
line 12 <qnet-datepicker #startDate [date]="startDate" (dateChange)="updateStart(startDate.date, startTime.value)"></qnet-datepicker>
the input
[date]
is taking a reference to the component itself via template reference variable #startDate
removing that fixes the issue.
Upvotes: 1