Как обнаружить события изменения bootstrap datetimepicker в angular2
Я использую загрузочный datetimepicker в angular 2
https://eonasdan.github.io/bootstrap-datetimepicker/
В моем шаблоне у меня есть:
<div class='input-group date datepicker'>
<input type='text' class="form-control" [(ngModel)]="date">
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar" (click)="getCalendar()"></span>
</span>
{{date}}
</div>
проблема в том, что когда я выбираю дату в календаре щелчком мыши, это не вызывает никакого события "изменения" (другими словами,ngModel
не уволили). Если я введу текстовое поле, то {{date}}
показывает мне значение плюс текст, который я набрал.
как я могу обнаружить изменения на текстовое поле, если пользователь нажимает на дату в селекторе, чтобы изменить ее?
5 ответов
проблема в том, что Angular не знает, что значение ввода изменилось, чтобы обновить ngModel. Еще одна странная вещь заключается в том, что bootstrap-datetimepicker не запускает событие изменения на входе - это требует некоторого обходного пути.
посмотреть этот рабочий пример:
<div class='input-group date datepicker'>
<input type='text' class="form-control" #datePicker [ngModel]="date" (blur)="date = datePicker.value">
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar" (click)="getCalendar()"></span>
</span>
{{date}}
</div>
обратите внимание на изменения:
-
[ngModel]="date"
: нам нужна только односторонняя привязка данных (от модели к виду), так как Angular не знает, когда значение ввода имеет изменено -
#datePicker
: Я создал локальную переменную, чтобы получить доступ к ее значению -
(blur)="date = datePicker.value"
: на размытие мы обновляем модель
проблема, как заявил другой отвечает, что ngModel не поднимая замены сторонняя библиотека. ngModel использует двустороннюю привязку данных. По существу, когда вы говорите
<div [(ngModel)]="date">
, что эквивалентно
<div [ngModel]="date" (ngModelChange)="date=$event">
.
что я сделал, так это создал директиву для испускания события ngModelChange следующим образом:
@Directive({
selector: [datepicker],
outputs: [
"ngModelChange"
]
})
export class DatePickerDirective {
//Emits changes to ngModel
ngModelChange = new EventEmitter();
el: JQuery;
//Obtains the handle to the jQuery element
constructor(el){
this.el = jQuery(el.nativeElement);
}
ngOnInit() {
this.el.datetimepicker({
//Initialization options
});
this.el.on('dp.change', (event) => {
var moment: Moment = event.date;
//Emit new value
this.ngModelChange.emit(date.format(/*However you want it formatted*/));
});
};
ngOnDestroy() {
//Clean up
this.el.data('DateTimePicker').destroy();
};
};
решение, опубликованное user3169887, отлично работало для меня, пока я не переключился с формы, управляемой шаблоном (использует ngModel), на реактивную форму.
глядя дальше в исходную проблему, я узнал, что Angular прослушивает событие "input", которое эти библиотеки datepicker не запускают. Мое решение было подправить директиву огонь "вход", а не испускать событие ngModelChange. Я протестировал эту директиву как с шаблонной формой, так и с реактивной формой и оба, казалось, работали.
import { Directive, ElementRef, Renderer, Input, OnInit } from "@angular/core";
declare var $: any;
@Directive({
selector: "[datepicker]"
})
export class DatePickerDirective implements OnInit {
@Input("datepicker")
private datepickerOptions: any = {};
private $el: any;
constructor(private el: ElementRef, private renderer: Renderer) {
this.$el = $(el.nativeElement);
}
ngOnInit() {
// Initialize the date picker
this.$el.datepicker(this.datepickerOptions)
// Angular is watching for the "input" event which is not fired when choosing
// a date within the datepicker, so watch for the "changeDate" event and manually
// fire the "input" event so that Angular picks up the change
// See: angular/modules/@angular/forms/src/directives/default_value_accessor.ts
.on("changeDate", (event) => {
let inputEvent = new Event("input", { bubbles: true });
this.renderer.invokeElementMethod(this.el.nativeElement, "dispatchEvent", [inputEvent]);
});
};
ngOnDestroy() {
this.$el.datepicker("destroy");
};
};
обратите внимание, что я использую другую библиотеку datepicker, поэтому я слушаю событие "changeDate", и ваша библиотека может запускать другое событие, например "dp.изменение."
не уверен, что это работает, но в соответствии с документами правильное событие для прослушивания -change
<div class='input-group date datepicker' (change)="date=$event">
попробовать ngModelChange
вместо change
.
<input class="form-control" (ngModelChange)="changeDate($event)"
[(ngModel)]="startRegistrationDate" ngbDatepicker #start="ngbDatepicker">
// to catch the event
changeDate(event: any) {
console.log(event);
}