如何在 angular2 中检测 bootstrap datetimepicker 更改事件
How to detect bootstrap datetimepicker change events within angular2
我在 angular 2
中使用 bootstrap 日期时间选择器
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>
问题是当我通过单击 select 日历上的日期时,它不会触发任何 "change" 事件(换句话说,不会触发 ngModel
)。如果我在文本框中键入内容,那么 {{date}}
会显示值加上我键入的文本。
如果用户单击 select 中的日期或要更改它,我如何检测文本框上的更改?
不确定这是否有效,但根据文档,要监听的正确事件是 change
<div class='input-group date datepicker' (change)="date=$event">
问题是 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 发布的解决方案对我非常有用,直到我从 template-driven 形式(使用 ngModel)切换到反应形式。
进一步研究原始问题,我了解到 Angular 正在侦听这些日期选择器库不会触发的 "input" 事件。我的解决方案是调整指令以触发 "input" 事件而不是发出 ngModelChange 事件。我用 template-driven 形式和反应形式测试了这个指令,两者似乎都有效。
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");
};
};
请注意,我使用的是不同的日期选择器库,因此我正在监听 "changeDate" 事件,您的库可能会触发不同的事件,例如 "dp.change"。
尝试 ngModelChange
而不是 change
。
<input class="form-control" (ngModelChange)="changeDate($event)"
[(ngModel)]="startRegistrationDate" ngbDatepicker #start="ngbDatepicker">
// to catch the event
changeDate(event: any) {
console.log(event);
}
我在 angular 2
中使用 bootstrap 日期时间选择器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>
问题是当我通过单击 select 日历上的日期时,它不会触发任何 "change" 事件(换句话说,不会触发 ngModel
)。如果我在文本框中键入内容,那么 {{date}}
会显示值加上我键入的文本。
如果用户单击 select 中的日期或要更改它,我如何检测文本框上的更改?
不确定这是否有效,但根据文档,要监听的正确事件是 change
<div class='input-group date datepicker' (change)="date=$event">
问题是 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 发布的解决方案对我非常有用,直到我从 template-driven 形式(使用 ngModel)切换到反应形式。
进一步研究原始问题,我了解到 Angular 正在侦听这些日期选择器库不会触发的 "input" 事件。我的解决方案是调整指令以触发 "input" 事件而不是发出 ngModelChange 事件。我用 template-driven 形式和反应形式测试了这个指令,两者似乎都有效。
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");
};
};
请注意,我使用的是不同的日期选择器库,因此我正在监听 "changeDate" 事件,您的库可能会触发不同的事件,例如 "dp.change"。
尝试 ngModelChange
而不是 change
。
<input class="form-control" (ngModelChange)="changeDate($event)"
[(ngModel)]="startRegistrationDate" ngbDatepicker #start="ngbDatepicker">
// to catch the event
changeDate(event: any) {
console.log(event);
}