我一直在为Angularjs寻找合适的日期选择器并决定使用 pickadate.js
因为它具有漂亮的移动UI以及允许角度集成的自定义指令,如本博文中所示
http://www.codinginsight.com/angularjs-and-pickadate/
我想在上面的博客文章中扩展指令,并在值发生变化时调用控制器中的函数。扩展指令的完整代码如下所示
angular.module('plunker').directive('pickADate', function () {
return {
restrict: "A",
scope: {
pickADate: '=',
minDate: '=',
maxDate: '=',
change: '='
},
link: function (scope, element, attrs) {
element.pickadate({
onSet: function (e) {
if (scope.$$phase || scope.$root.$$phase) // we are coming from $watch or link setup
return;
var select = element.pickadate('picker').get('select'); // selected date
scope.$apply(function () {
if (e.hasOwnProperty('clear')) {
scope.pickADate = null;
return;
}
if (!scope.pickADate)
scope.pickADate = new Date(0);
scope.pickADate.setYear(select.obj.getFullYear());
// Interesting: getYear returns only since 1900. Use getFullYear instead.
// It took me half a day to figure that our. Ironically setYear()
// (not setFullYear, duh) accepts the actual year A.D.
// So as I got the $#%^ 114 and set it, guess what, I was transported to ancient Rome 114 A.D.
// That's it I'm done being a programmer, I'd rather go serve Emperor Trajan as a sex slave.
scope.pickADate.setMonth(select.obj.getMonth());
scope.pickADate.setDate(select.obj.getDate());
});
},
onClose: function () {
element.blur();
}
});
function updateValue(newValue) {
if (newValue) {
scope.pickADate = (newValue instanceof Date) ? newValue : new Date(newValue);
// needs to be in milliseconds
element.pickadate('picker').set('select', scope.pickADate.getTime());
} else {
element.pickadate('picker').clear();
scope.pickADate = null;
}
}
updateValue(scope.pickADate);
element.pickadate('picker').set('min', scope.minDate ? scope.minDate : false);
element.pickadate('picker').set('max', scope.maxDate ? scope.maxDate : false);
scope.$watch('pickADate', function (newValue, oldValue) {
if (newValue == oldValue)
return;
updateValue(newValue);
// call change function
scope.change;
}, true);
scope.$watch('minDate', function (newValue, oldValue) {
element.pickadate('picker').set('min', newValue ? newValue : false);
}, true);
scope.$watch('maxDate', function (newValue, oldValue) {
element.pickadate('picker').set('max', newValue ? newValue : false);
}, true);
}
};
});
我现在可以将此指令与change事件一起使用,如下面的HTML
所示<input type="text" pick-a-date="curDate" change="onChange()" />
它可以工作但是OnChange事件会针对单个更改多次触发。关于如何才能让它只发射一次的任何想法?我已经创建了一个用于演示问题的plunker
http://plnkr.co/edit/3NcaAknd4GpelJxHWUyv
单击文本字段并选择日期。您将看到计数器变量多次更新以进行单个日期更改。
答案 0 :(得分:0)
您已使用change
代替pick-a-date
在'='
指令中绑定'&'
。
对于像回调函数这样的表达式,建议使用后一种隔离范围绑定。
AngularJS文档中关于directives的相关建议:
最佳做法:当您希望指令公开API以绑定行为时,请在范围选项中使用
&attr
。
答案 1 :(得分:0)
由于@miqid建议在指令和控制器之间绑定一个函数,使用'&'
('='
只能用于指令和控制器之间的绑定范围变量。)
此外,您还需要对当前代码进行一项更改。 updateValue()
中的函数scope.change未被执行,因为它已被引用为scope.change。必须将其更改为scope.change()
。
我已经分叉你的plunker并修改它以修复上述变化。
修正了工作人员:http://plnkr.co/edit/oEpOxE21dXre28FpKoMc?p=preview
计数器只会更新一次。如果这有帮助,请告诉我。