Angular uib-datepicker切换年月时调用函数的实现方法
我之前刚好碰到过一模一样的需求,给你分享几个经过验证的可行方案:
方案一:监听Datepicker内部的
activeDate变更(推荐) Angular UI Bootstrap的datepicker内部维护了一个activeDate属性,它代表当前日历面板显示的年月对应的基准日期(比如显示2024年5月时,activeDate通常是2024-05-01)。不管是点击前后箭头切换月份,还是通过年月选择器直接跳转,这个值都会同步更新。我们可以通过自定义指令监听这个属性的变化,再判断是否需要触发指定函数。
代码示例
首先在模板中给datepicker添加自定义指令,并绑定要触发的函数:
<uib-datepicker ng-model="selectedDate" datepicker-nav-trigger on-nav-change="handleMonthYearSwitch()" ></uib-datepicker>
然后实现自定义指令:
angular.module('yourApp').directive('datepickerNavTrigger', function() { return { require: 'uibDatepicker', scope: { onNavChange: '&', ngModel: '=' }, link: function(scope, element, attrs, datepickerCtrl) { // 深度监听activeDate的变化(Date对象是引用类型,需深度比较) scope.$watch( () => datepickerCtrl.activeDate, (newVal, oldVal) => { // 排除初始化时的第一次触发,且确认日期未被选择 if (newVal && oldVal && !angular.equals(newVal, oldVal) && !scope.ngModel) { scope.onNavChange(); } }, true ); } }; });
方案二:直接绑定导航元素的点击/变更事件
如果不想依赖datepicker内部的属性,也可以直接监听面板上导航元素的DOM事件——比如前后箭头按钮的点击、年月选择器的下拉变更,触发时检查是否未选择日期,再调用目标函数。
代码示例
同样先在模板中添加指令:
<uib-datepicker ng-model="selectedDate" datepicker-dom-trigger on-nav-change="handleMonthYearSwitch()" ></uib-datepicker>
然后实现指令:
angular.module('yourApp').directive('datepickerDomTrigger', function() { return { scope: { onNavChange: '&', ngModel: '=' }, link: function(scope, element) { // 监听前后箭头按钮的点击 element.on('click', '.btn-prev, .btn-next', function() { if (!scope.ngModel) { // 手动触发Angular的digest循环,确保函数执行 scope.$apply(() => scope.onNavChange()); } }); // 监听年月选择器的下拉变更 element.on('change', '.datepicker-switch select', function() { if (!scope.ngModel) { scope.$apply(() => scope.onNavChange()); } }); } }; });
注意事项
- 方案一更稳定,因为它依赖datepicker的内部控制器属性,不会因为UI结构变化(比如组件版本更新导致按钮类名变更)而失效。
- 方案二中使用原生DOM事件时,必须用
scope.$apply()包裹回调,否则Angular无法感知到事件触发,绑定的函数不会执行。 - 如果使用的是
uib-datepicker-popup组件,需要确保指令作用在popup展开后的datepicker元素上,或者调整选择器来定位导航元素。
内容的提问来源于stack exchange,提问作者Miguel Cantó Bataller
相关产品推荐
相关产品推荐

