Angular2 RC7 ng2-datetime错误 - ($(...)。datepicker不是函数)

时间:2016-11-10 08:07:31

标签: angular ng2-bootstrap

我声明了一些var并将$替换为jQuery。

1.i声明var jQuery:any;    2.将$替换为jQuery; (ts中的错误清除)    3.在system.config.json中配置并在app.module中导入    4.我在node-module

中有bootstrap-datepicker

错误是日期时间输入框没有工作,错误在控制台中显示如此($(...)。datepicker不是函数)。我在ts中将$更改为jQuery。请帮助我。

ng2-datetime.ts

  import {
            Component, Output, Input, EventEmitter, HostListener, AfterViewInit, OnDestroy,
            SimpleChanges, OnChanges
        } from '@angular/core';
        import { ControlValueAccessor, NgControl } from '@angular/forms';
        import { TimepickerEvent } from './timepicker-event-interface';
        declare var jQuery: any; 

    @Component({
        selector: 'datetime',
        template: `
        <div class="form-inline">
            <div id="{{idDatePicker}}" class="input-group date">
                <input type="text" class="form-control"
                       [attr.readonly]="readonly"
                       [attr.placeholder]="datepickerOptions.placeholder || 'Choose date'"
                       [(ngModel)]="dateModel"
                       (keyup)="checkEmptyValue($event)"/>
                <div class="input-group-addon">
                    <span [ngClass]="datepickerOptions.icon || 'glyphicon glyphicon-th'"></span>
                </div>
            </div>
            <div class="input-group bootstrap-timepicker timepicker">
                <input id="{{idTimePicker}}" type="text" class="form-control input-small" 
                       [attr.readonly]="readonly"
                       [attr.placeholder]="timepickerOptions.placeholder || 'Set time'"
                       [(ngModel)]="timeModel"
                       (keyup)="checkEmptyValue($event)">
                <span class="input-group-addon"><i [ngClass]="timepickerOptions.icon || 'glyphicon glyphicon-time'"></i></span>
            </div>
            <button *ngIf="hasClearButton" type="button" (click)="onClearClick()">Clear</button>
        </div>
       `
    })
    export class NKDatetime implements ControlValueAccessor, AfterViewInit, OnDestroy, OnChanges {
        @Output()
        dateChange: EventEmitter<Date> = new EventEmitter<Date>();

        @Input('timepicker')
        timepickerOptions: any = {};

        @Input('datepicker')
        datepickerOptions: any = {};

        @Input('hasClearButton')
        hasClearButton: boolean = false;

        @Input()
        readonly: boolean = null;

        date: Date; // ngModel
        dateModel: string;
        timeModel: string;

        // instances
        datepicker: any;
        timepicker: any;

        private idDatePicker: string = uniqueId('q-datepicker_');
        private idTimePicker: string = uniqueId('q-timepicker_');

        @HostListener('dateChange', ['$event'])
        onChange = (_: any) => {
        };
        onTouched = () => {
        };

        constructor(ngControl: NgControl) {
            ngControl.valueAccessor = this; // override valueAccessor
        }

        ngAfterViewInit() {
            this.init();
        }

        ngOnDestroy() {
            if (this.datepicker) {
                this.datepicker.datepicker('destroy');
            }
            if (this.timepicker) {
                this.timepicker.timepicker('remove');
            }
        }

        ngOnChanges(changes: SimpleChanges) {
            if (changes) {
                if (changes['datepickerOptions'] && this.datepicker) {
                    this.datepicker.datepicker('destroy');

                    if (changes['datepickerOptions'].currentValue) {
                        this.datepicker = null;
                        this.init();
                    } else if (changes['datepickerOptions'].currentValue === false) {
                        this.datepicker.remove();
                    }
                }
                if (changes['timepickerOptions'] && this.timepicker) {
                    this.timepicker.timepicker('remove');

                    if (changes['timepickerOptions'].currentValue) {
                        this.timepicker = null;
                        this.init();
                    } else if (changes['timepickerOptions'].currentValue === false) {
                        this.timepicker.parent().remove();
                    }
                }
            }
        }

        writeValue(value: any): void {
            this.date = value;
            if (isDate(this.date)) {
                setTimeout(() => {
                    this.updateModel(this.date);
                }, 0);
            }
        }

        registerOnChange(fn: (_: any) => void): void {
            this.onChange = fn;
        }

        registerOnTouched(fn: () => void): void {
            this.onTouched = fn;
        }

        checkEmptyValue(e: any) {
            const value = e.target.value;
            if (value === '' && (
                    this.timepickerOptions === false ||
                    this.datepickerOptions === false ||
                    (this.timeModel === '' && this.dateModel === '')
                )) {
                this.dateChange.emit(null);
            }
        }

        onClearClick() {
            this.dateChange.emit(null);
            if (this.timepicker) {
                this.timepicker.timepicker('setTime', null);
            }
            this.updateDatepicker(null);
        }

        //////////////////////////////////

        private init(): void {
            if (!this.datepicker && this.datepickerOptions !== false) {
                let options = jQuery.extend({ enableOnReadonly: !this.readonly }, this.datepickerOptions);
                this.datepicker = (<any>jQuery('#' + this.idDatePicker)).datepicker(options);
                this.datepicker
                    .on('changeDate', (e: any) => {
                        let newDate: Date = e.date;

                        if (isDate(this.date) && isDate(newDate)) {
                            // get hours/minutes
                            var h = this.date.getHours();
                            var m = this.date.getMinutes();
                            newDate.setHours(h);
                            newDate.setMinutes(m);
                        }

                        this.date = newDate;
                        this.dateChange.emit(newDate);
                    });
            } else if (this.datepickerOptions === false) {
                (<any>jQuery('#' + this.idDatePicker)).remove();
            }

            if (!this.timepicker && this.timepickerOptions !== false) {
                let options = jQuery.extend({ defaultTime: false }, this.timepickerOptions);
                this.timepicker = (<any>jQuery('#' + this.idTimePicker)).timepicker(options);
                this.timepicker
                    .on('changeTime.timepicker', (e: TimepickerEvent) => {
                        let { meridian, hours } = e.time;

                        if (meridian) {
                            // has meridian -> convert 12 to 24h
                            if (meridian === 'PM' && hours < 12) {
                                hours = hours + 12;
                            }
                            if (meridian === 'AM' && hours === 12) {
                                hours = hours - 12;
                            }
                            hours = parseInt(this.pad(hours));
                        }

                        if (!isDate(this.date)) {
                            this.date = new Date();
                            this.updateDatepicker(this.date);
                        }

                        this.date.setHours(hours);
                        this.date.setMinutes(e.time.minutes);
                        this.dateChange.emit(this.date);
                    });
            } else if (this.timepickerOptions === false) {
                (<any>jQuery('#' + this.idTimePicker)).parent().remove();
            }
        }

        private updateModel(date: Date): void {
            this.updateDatepicker(date);

            // update timepicker
            if (this.timepicker !== undefined) {
                let hours = date.getHours();
                if (this.timepickerOptions.showMeridian) {
                    // Convert 24 to 12 hour system
                    hours = (hours === 0 || hours === 12) ? 12 : hours % 12;
                }
                const meridian = date.getHours() >= 12 ? ' PM' : ' AM';
                const time =
                    this.pad(hours) + ':' +
                    this.pad(this.date.getMinutes()) +
                    (this.timepickerOptions.showMeridian || this.timepickerOptions.showMeridian === undefined
                        ? meridian : '');
                this.timepicker.timepicker('setTime', time);
                this.timeModel = time; // fix initial empty timeModel bug
            }
        }

        private updateDatepicker(value?: any) {
            if (this.datepicker !== undefined) {
                this.datepicker.datepicker('update', value);
            }
        }

        private pad(value: any): string {
            return value.toString().length < 2 ? '0' + value : value.toString();
        }
    }

    let id: number = 0;
    function uniqueId(prefix: string): string {
        return prefix + ++id;
    }

    function isDate(obj: any) {
        return Object.prototype.toString.call(obj) === '[object Date]';
    }
System.config.json
/**
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      moment:'node_modules/moment/moment.js',
      '@ng-bootstrap/ng-bootstrap': 'node_modules/@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap.js',

      'mydatepicker' :'npm:mydatepicker',


      'ng2-datetime': "npm:ng2-datetime",
      // our app is within the app folder
      app: 'app',
      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
      // other libraries
      'rxjs':                       'npm:rxjs',
      'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      'ng2-datetime': {
                main: './ng2-datetime.js',
                defaultExtension: 'js'
            },
      mydatepicker : {
        main :'./index.js',
        defaultExtension:'js'
      },
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
      rxjs: {
        defaultExtension: 'js'
      },
      'angular2-in-memory-web-api': {
        main: './index.js',
        defaultExtension: 'js'
      }
    }
  });
})(this);
  

错误控制台图片

enter image description here

3 个答案:

答案 0 :(得分:0)

让我们导入一些libs

import 'bootstrap/dist/css/bootstrap.css';
import 'jquery/dist/jquery.min.js';
import 'ng2-datetime/src/vendor/bootstrap-datepicker/bootstrap-datepicker3.min.css';
import 'ng2-datetime/src/vendor/bootstrap-datepicker/bootstrap-datepicker.min.js';
import 'ng2-datetime/src/vendor/bootstrap-timepicker/css/bootstrap-timepicker.min.css';
import 'ng2-datetime/src/vendor/bootstrap-timepicker/js/bootstrap-timepicker.js';

我正在使用angular-seed,所以我将在配置文件中的项目中添加上面的libs 请在here

了解详情

答案 1 :(得分:0)

之后将这些行导入index.html
<script src="node_modules/systemjs/dist/system.src.js"></script>

行:

<script src="node_modules/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css">
<script src="node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
<link rel="stylesheet" href="node_modules/bootstrap-timepicker/css/bootstrap-timepicker.min.css">
<script src="node_modules/bootstrap-timepicker/js/bootstrap-timepicker.js"></script>

答案 2 :(得分:-1)

在Angular2中,主要的想法是不使用jQuery,你可以避免它。如果您的某些依赖项使用它,您仍应将其作为依赖项包含在模块加载器中。

类型错误失败'datepicker'不是函数,但由于ZoneJS / UMD干扰了您的错误记录,可能是您的“datepicker”依赖项未正确加载(或者未提供正确地通过Angular2模块加载器),或者你的jQuery变量($)不可用。