AngularJS日期选择器多次触发onchange事件

AngularJS日期选择器多次触发onchange事件,angularjs,datepicker,angularjs-directive,Angularjs,Datepicker,Angularjs Directive,我一直在为Angularjs寻找合适的日期选择器,并决定使用 pickadate.js 因为它有漂亮的移动用户界面和一个自定义指令,允许角度集成,如本文所示 我想用一个事件来扩展上面博客文章中的指令,以便在值更改时调用控制器中的函数。扩展指令的完整代码如下所示 angular.module('plunker').directive('pickADate', function () { return { restrict: "A", scope: {

我一直在为Angularjs寻找合适的日期选择器,并决定使用 pickadate.js

因为它有漂亮的移动用户界面和一个自定义指令,允许角度集成,如本文所示

我想用一个事件来扩展上面博客文章中的指令,以便在值更改时调用控制器中的函数。扩展指令的完整代码如下所示

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);
        }
    };
});
现在,我可以将此指令与更改事件一起使用,如下所示

<input type="text" pick-a-date="curDate" change="onChange()" />

它可以工作,但是OnChange事件会为一次更改触发多次。你知道我怎样才能让它只开火一次吗?我创建了一个plunker来演示这个问题


单击文本字段并选择日期。您将看到计数器变量因一次日期更改而多次更新。

您已使用
'='
而不是
'&
更改
绑定到
拾取日期
指令中

对于回调函数之类的表达式,建议使用后一种隔离作用域绑定

AngularJS文件中关于以下方面的相关建议:

最佳实践:当您希望指令公开用于绑定行为的API时,请在范围选项中使用
&attr


正如@miqid建议在指令和控制器之间绑定函数一样,请使用
'&'
'='
应仅用于绑定指令和控制器之间的作用域变量。)

此外,还必须对当前代码进行一项更改。
updateValue()
中的函数scope.change未被执行,因为它被称为scope.change。必须将其更改为
scope.change()

我已经分叉了你的Plunk并修改了它以修复上述更改

固定工作插销:

计数器仅更新一次以进行更改。让我知道这是否有帮助