如何让我的指令只在onchange上启动?

时间:2013-01-24 04:34:37

标签: angularjs

我已经定义了这样的指令:

angular.module('MyModule', [])
    .directive('datePicker', function($filter) {
        return {
            require: 'ngModel',
            link: function(scope, elem, attrs, ctrl) {
                ctrl.$formatters.unshift(function(modelValue) {
                    console.log('formatting',modelValue,scope,elem,attrs,ctrl);
                    return $filter('date')(modelValue, 'MM/dd/yyyy');
                });
                ctrl.$parsers.unshift(function(viewValue) {
                    console.log('parsing',viewValue);
                    var date = new Date(viewValue);
                    return isNaN(date) ? '' : date;
                });
            }
        }
    });

每次我在文本框中键入一个键时,解析器似乎都会触发 - 默认事件究竟是什么,是keyup还是input?如何将其更改为仅onchange?实际上没有必要经常开火。

此外,我实际上是使用jQuery UI的datepicker操作此输入的内容。单击日历时,它似乎不会触发导致模型更新/解析器被触发的相应事件。我 I can force an event to be fired但我需要知道哪一个。


尝试使用scope.$apply(),但似乎没有任何帮助:

.directive('datepicker', function($filter) {
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
            $(elem).datepicker({
                onSelect: function(dateText, inst) {
                    console.log(dateText, inst);
                    scope.$apply();
                }
            });
            ctrl.$formatters.unshift(function(modelValue) {
                console.log('formatting',modelValue);
                return $filter('date')(modelValue, attrs.datePicker || 'MM/dd/yyyy');
            });
            ctrl.$parsers.unshift(function(viewValue) {
                console.log('parsing',viewValue);
                return new Date(viewValue);
            });
        }
    }
})

我不认为解决方案given here对我有用,因为(a)我想使用datepicker属性值来选择日期格式或其他选项,但更重要的是,(b)似乎当我想要一个实际的日期对象时,将一个字符串传递回模型...因此必须完成某种形式的解析并应用于ng-model

1 个答案:

答案 0 :(得分:2)

这里我创建了一个mo-change-proxy指令,它与ng-model一起使用,只在更改时才更新代理变量。

在这个演示中,我甚至包含了日期输入的改进指令。看看。
演示: http://plnkr.co/edit/DBs4jX9alyCZXt3LaLnF?p=preview

angModule.directive('moChangeProxy', function ($parse) {
    return {
        require:'^ngModel',
        restrict:'A',
        link:function (scope, elm, attrs, ctrl) {
            var proxyExp = attrs.moChangeProxy;
            var modelExp = attrs.ngModel;
            scope.$watch(proxyExp, function (nVal) {
                if (nVal != ctrl.$modelValue)
                    $parse(modelExp).assign(scope, nVal);
            });
            elm.bind('blur', function () {
                var proxyVal = scope.$eval(proxyExp);
                if(ctrl.$modelValue != proxyVal) {
                    scope.$apply(function(){
                        $parse(proxyExp).assign(scope, ctrl.$modelValue);
                    });
                }
            });
        }
    };
});