web-dev-qa-db-ja.com

検出方法bootstrap datetimepicker changeangle2内のイベントを変更する

bootstrap datetimepicker in 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}}は、値と入力したテキストを表示します。

ユーザーがセレクターの日付をクリックして変更する場合、どのようにテキストボックスの変更を検出できますか?

15
Sireini

問題は、AngularはngModelを更新するために入力値が変更されたことを知らないことです。別の奇妙なことは、bootstrap-datetimepickerが入力のchangeイベントをトリガーしないことです。回避策が必要です。

この作業例を参照してください。

<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":ぼかしでモデルを更新します
15
Cosmin Ababei

他の回答で述べられている問題は、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();
    };
};
7

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」などの別のイベントを起動する可能性があります。

5
jaggedaz

ngModelChangeの代わりにchangeを試してください。

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

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

これが機能するかどうかはわかりませんが、ドキュメントによると、リッスンする適切なイベントはchangeです

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