【问题标题】:How to detect bootstrap datetimepicker change events within angular2如何检测 angular2 中的引导 datetimepicker 更改事件
【发布时间】:2016-07-05 09:46:34
【问题描述】:

我在 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}} 会显示值加上我输入的文本。

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

【问题讨论】:

  • 也许你可以使用来自 ng2-bootstrap 的日期选择器?

标签: angular angular-ngmodel bootstrap-datetimepicker


【解决方案1】:

尝试ngModelChange 而不是change

<input class="form-control" (ngModelChange)="changeDate($event)"
      [(ngModel)]="startRegistrationDate" ngbDatepicker #start="ngbDatepicker">

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

【讨论】:

  • 只有当你使用 ngmodel 时,才会使用响应式表单
  • @Solid_Metal 你现在可以使用[ngModelOptions]="{standalone: true}" 来解决这个问题
【解决方案2】:

user3169887 发布的解决方案对我很有效,直到我从模板驱动的表单(使用 ngModel)切换到反应式表单。

进一步研究原始问题,我了解到 Angular 正在侦听这些日期选择器库不会触发的“输入”事件。我的解决方案是调整指令以触发“输入”事件,而不是发出 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");
    };
};

请注意,我使用的是不同的日期选择器库,因此我正在监听“changeDate”事件,而您的库可能会触发不同的事件,例如“dp.change”。

【讨论】:

  • 效果很好,适应 ui DatePicker,使用 'onSelect'
  • 看起来更好...我要试试这个
【解决方案3】:

其他答案所述的问题是 ngModel 没有接受第三方库所做的更改。 ngModel 使用双向数据绑定。本质上,当你说

&lt;div [(ngModel)]="date"&gt;

相当于

&lt;div [ngModel]="date" (ngModelChange)="date=$event"&gt;.

我所做的是创建一个指令来发出 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();
    };
};

【讨论】:

  • ElementRef 没有“开”。它可能在 rc5 左右被删除了。现在应该是this.el.nativeElement.onchange= function(event) { } 吗? angular.io/docs/js/latest/api/core/index/ElementRef-class.html
  • 应该是this.el.nativeElement.onchange= (event) =&gt; { },因为它修复了this问题
  • 很高兴知道。将 this.el 更改为 JQuery 类型(需要 JQuery 类型来执行此操作,除非您足够大胆地使用“any”),这无论如何都是 this.el 的更好表示。
  • (ngModelChange) 而不是 (change) 正是我所需要的。
【解决方案4】:

问题在于 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":我们在模糊时更新模型

【讨论】:

  • 要去看看刚刚看到你的答案:)
  • @Beginnerprogrammer 很高兴它对您有所帮助。这不是一个完美的解决方案,因为模型只有在输入变得模糊时才会更新。
  • 你还知道如何将 this 绑定到对象吗?
  • @Beginnerprogrammer 我不明白。能详细点吗?
【解决方案5】:

不确定这是否有效,但根据文档,要监听的正确事件是 change

<div class='input-group date datepicker' (change)="date=$event">

【讨论】:

  • {{date}}
    像这样它不工作..
  • 您可以试试&lt;div class='input-group date datepicker' (change)="handleChange($value)"&gt; 并添加handleChange($event) { console.log(event); }。我的回答也有错误 - 已更新。 (将$value 更改为$event
  • 问题是引导 datetimepicker 不会触发输入的更改事件。事实上,它有一个自定义事件“dp.change”,但 angular 似乎无法在 (dp.change) 中捕捉到它。
猜你喜欢
  • 2017-02-13
  • 1970-01-01
  • 2016-02-05
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2016-07-07
  • 2017-04-28
相关资源
最近更新 更多