使用Angular与Moment.js构建日期选择器时遇clone函数错误求助
解决Angular日期选择器中的"TypeError: scope.viewDate.clone is not a function"错误
我一眼就揪出问题所在了——你把scope.viewDate直接赋值成了moment构造函数本身,而不是一个moment.js的日期实例!clone()是moment实例专属的方法,直接调用构造函数的话肯定找不到这个方法,这就是报错的核心原因。
错误根源分析
看你这段代码:
scope.viewDate = moment;
这里的moment是一个函数,不是已经创建好的日期对象。要调用clone()、startOf()这些方法,你必须先通过moment()(或带参数的moment('2024-05-20'))创建一个具体的moment实例才行。
修复方案
只需要把scope.viewDate的赋值改成创建moment实例的形式,再给你补充几个优化细节:
angular.module('myApp') .directive('datepicker', function () { return{ restrict: 'EA', scope: true, require: 'ngModel', link: function (scope, elm, attr, ngModel) { // 修复:创建当前时间的moment实例,而非赋值构造函数 scope.viewDate = moment(); // 可选:给选中日期一个初始值,后续也可通过ngModel同步 var selectedDate = moment(); function generateDays() { scope.days = []; var startOfSelectedDate = moment.isMoment(selectedDate) ? selectedDate.clone().startOf('day') : null; // 现在viewDate是实例,能正常调用clone()了 var startDate = scope.viewDate.clone().startOf('month').startOf('week').startOf('day'); var endDate = scope.viewDate.endOf('month').endOf('week').endOf('day'); // 用moment官方推荐的isBefore()代替<,比较更可靠 while (startDate.isBefore(endDate)){ scope.days.push({ label: startDate.date(), inMonth: startDate.month() === scope.viewDate.month() && startDate.year() === scope.viewDate.year(), date: startDate.valueOf(), // 加上'day'精度,避免时间部分干扰选中判断 selected: startDate.isSame(selectedDate, 'day') }); startDate.add(1, 'day'); } } generateDays(); } } });
额外小建议
- 用
isBefore()代替<比较日期:这是moment官方推荐的比较方式,能避免原生JS比较日期对象时的潜在问题。 - 给
isSame()加精度参数:比如isSame(selectedDate, 'day'),确保只要日期相同就判定为选中,不受时分秒影响。 - 绑定ngModel:如果需要和父组件的日期值同步,记得在link函数里监听ngModel的变化,或者把选中的日期同步回ngModel,这样指令才更实用。
内容的提问来源于stack exchange,提问作者NevrMore
相关产品推荐
相关产品推荐

