我如何在Angular 2中使用mdbootstrap?

时间:2016-12-05 13:01:29

标签: jquery angular typescript

在我的任务中,我使用http://mdbootstrap.com/javascript/date-picker 我如何在angular 2组件中使用日期选择器,我必须在jquery中将此代码添加到组件中的typescript组件$('.datepicker').pickadate();

my_component.ts

import { Component, OnInit, ElementRef } from '@angular/core';
declare var $: any;

@Component({
// selector: 'clients',
templateUrl: './src/client/app/views/clients.html',
})
export class ClientsModel implements OnInit {
constructor(private _elmRef: ElementRef) {}
/* this code not work*/
ngOnInit() {
    $(this._elmRef.nativeElement)
        .find('#date-picker-example')
        .on('click', function(){
            $('#date-picker-example').pickadate();
        });
}
}

my_component.html

<div class="md-form col-xl-2 col-lg-3 col-md-4 col-sm-6 col-xs-12" style="margin-top: 1%;">
     <input type="text" id="date-picker-example" class="form-control datepicker">
     <label for="date-picker-example">Date begin</label>
</div>

1 个答案:

答案 0 :(得分:0)

如果您想使用MDB日期选择器,我不认为您可以使用jQuery。我为自己的项目编写了一个包装器,希望它对你也有帮助。我将其基于this article,它向您展示如何制作适用于[(ngModel)]的自定义组件。我还要求以与显示日期不同的格式保存日期,这增加了一些您可能不需要处理的复杂性。

值得注意的是,MDB日期选择器在内部使用pickadate.js,因此您也可以使用整个API。

&#13;
&#13;
import { Component, forwardRef, ViewChild, ElementRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

const noop = () => {
};

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => DatePickerComponent),
  multi: true
};

// Wrapper component for MDB's date picker, which is in turn a wrapper for pickadate.js.
// Uses the approach outlined here: http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel
@Component({
  selector: 'date-picker',
  template: `<input #element class="form-control" [attr.data-value]="value">`,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class DatePickerComponent implements ControlValueAccessor, OnChanges {

  // we need the native element here because we have to call the .pickadate() function on our element.
  @ViewChild('element') element: ElementRef;

  //The string representation of the currently selected date in the yyyy-mm-dd format.
  private innerValue: any = '';

  // A js date object representing the currently selected date.
  private innerValueDate: Date = null;

  // The format that actually gets displayed to the user, but not bound to anything directly.
  private dateFormat: string = 'd mmm yyyy';

  // The jquery object that is our api to pickadate.js.
  private pickerObject: any;

  //Placeholders for the callbacks which are later provided by the Control Value Accessor
  private onTouchedCallback: () => void = noop;
  private onChangeCallback: (_: any) => void = noop;

  // Minimum date the user can select
  @Input() minDate: Date;

  // If true and date is null, valid will return false, invalid will return true.
  @Input() required: boolean;

  // True after the user has opened and closed the date picker.  No way to reset it currently.
  public touched: boolean;

  //get accessor used in the template.
  get value(): string {
    return this.innerValue;
  };

  ngOnInit() {
    // Wire up the pickadate plugin to our native element.
    let element: any = $(this.element.nativeElement);

    let $pickerInput = element.pickadate({
      format: this.dateFormat,
      // If you are using non-standard formats when setting the value, pickadate requires that you pass in
      // formatSubmit tells the plugin how to parse them.
      formatSubmit: 'yyyy-MM-dd',
      onSet: context => {
        // For ngModel to work we need to let angular know this control has been touched.
        this.touched = true;
        this.onTouchedCallback();

        // Parse the date and set our internal tracking values.
        this.setValue(context.select);

        // Let angular know our value has changed.
        this.onChangeCallback(this.innerValue);
      },
      onClose: () => {
        this.touched = true;
        this.onTouchedCallback();

        // hack to get around this MDB date picker bug:  https://github.com/amsul/pickadate.js/issues/160
        $(document.activeElement).blur();
      }
    });

    // Keep track of the picker object we just created so we can call its apis later.
    this.pickerObject = $pickerInput.pickadate('picker');
    this.pickerObject.set('min', this.minDate);
  }

  // Properties to give this some of the same behavior/interface as a native control.
  get valid(): boolean {
    return this.required ? !!this.value : true;
  }

  get invalid(): boolean {
    return !this.valid;
  }

  get errors(): any {
    return this.valid ? null : { required: true };
  }

  // Used if you want to show the date picker programatically.
  public showDatePicker($event) {
    this.pickerObject.open();

    // If you don't stopPropagation() on this event, the picker doesn't open.
    // https://github.com/amsul/pickadate.js/issues/481
    if ($event) {
      $event.stopPropagation();
    }
  }

  // writeValue, registerOnChange, and registerOnTouched are from ControlValueAccessor interface
  writeValue(value: any) {
    this.setValue(value);
    this.pickerObject.set('select', this.innerValueDate);
  }

  registerOnChange(fn: any) {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: any) {
    this.onTouchedCallback = fn;
  }

  // Get notified when minDate changes so we can tell the pickadate plugin to respond accordingly.
  ngOnChanges(changes: SimpleChanges): void {
    // this actually gets called before ngOnInit, so the pickerObject may not be there yet.
    if (this.pickerObject && changes['minDate']) {
      this.pickerObject.set('min', this.minDate);
    }
  }

  // ***** Helper functions ******//
  // Parse and test the new value, but don't notify angular or anything in here.
  private setValue(value) {
    if (!value) {
      this.innerValue = '';
      this.innerValueDate = null;
    } else {
      let newValueDate: Date = new Date(Date.parse(value));
      if (!this.datesAreEqual(this.innerValueDate, newValueDate)) {
        this.innerValue = this.formatDate(newValueDate);
        this.innerValueDate = newValueDate;
      }
    }
  }

  // Compare two dates' values to see if they are equal.
  datesAreEqual(v1: Date, v2: Date) {
    if (v1 === null && v2 === null) {
      return true;
    } else if (!v1 || !v2) {
      return false;
    }
    return v1.getTime() === v2.getTime();
  }

  // There are lots more robust ways of formatting dates but since this is just an internal representation,
  // we can just do something simple and convert the date to yyyy-mm-dd.
  formatDate(d: Date) {
    if (d === null) {
      return null;
    }
    return d.getFullYear() + '-' + ('0'+(d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2);
  }
}
&#13;
&#13;
&#13;