如何在angular2中检测引导datetimepicker更改事件

如何在angular2中检测引导datetimepicker更改事件,angular,angular-ngmodel,bootstrap-datetimepicker,Angular,Angular Ngmodel,Bootstrap Datetimepicker,我正在使用angular 2中的引导datetimepicker 在我的模板中,我有: <div class='input-group date datepicker'> <input type='text' class="form-control" [(ngModel)]="date"> <span class="input-group-addon"> <span class="glyphicon

我正在使用angular 2中的引导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}将显示该值加上我键入的文本


如果用户单击选择器中的日期进行更改,如何检测文本框上的更改?

不确定这是否有效,但根据文档,正确的事件是更改


问题是Angular不知道输入值已更改以更新ngModel。另一件奇怪的事情是引导datetimepicker不会触发输入上的更改事件-这需要一些解决方法

请参见此工作示例: 请注意以下更改:

[ngModel]=date:我们只需要从模型到视图的单向数据绑定,因为Angular不知道输入的值何时发生了更改 datePicker:我创建了一个局部变量来访问它的值 blur=date=datePicker.value:blur时更新模型
其他答案指出的问题是,ngModel没有接受第三方图书馆所做的更改。ngModel使用双向数据绑定。基本上,当你说

这相当于

我所做的是创建一个指令来发出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正在侦听这些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。

尝试ngModelChange而不是change


也许您可以使用ng2引导中的日期选择器?{{date}}像这样它不起作用..你能尝试添加一个handleChange$event{console.logevent;}吗。我的回答也有一个错误-更新。将$value更改为$event问题在于引导datetimepicker不会触发输入上的更改事件。事实上,它有一个自定义事件dp.change,但angular似乎无法在dp.change中捕捉到它。要查看它,只需看到您的答案:@初学者程序员我很高兴它帮助了您。这不是一个完美的解决方案,因为只有当输入变得模糊时,模型才会更新。你还知道如何将它绑定到对象上吗?@初学者程序员我不明白。你能详细说明一下吗?{{constraint}}ElementRef没有启用。它可能在rc5左右被移除。现在应该是这个.el.nativeElement.onchange=functionevent{}吗?应该是这个.el.nativeElement.onchange=event=>{},因为它修复了这个问题。将this.el更改为JQuery类型需要JQuery类型才能执行此操作,除非您足够大胆,可以使用“any”来更好地表示此.el anyways.ngModelChange而不是change正是我所需要的。效果很好,适应ui DatePicker,使用“onSelect”看起来更好。。。我将尝试这一个只有当你使用ngmodel,不会与反应form@Solid_Metal您现在可以使用[ngModelOptions]={standalone:true}来解决此问题
@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();
    };
};
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");
    };
};
<input class="form-control" (ngModelChange)="changeDate($event)"
      [(ngModel)]="startRegistrationDate" ngbDatepicker #start="ngbDatepicker">

// to catch the event
changeDate(event: any) {
  console.log(event);
}