2

我最近将我的 AngularJS 框架从 1.2.0-rc.2 升级到了 1.2.0 版本,并遇到了一个我还没有找到解决办法的奇怪问题。我之前解决的问题是强制输入字段在 on-blur 事件而不是 on-change 事件上触发。我最初使用的指令的代码是:

angular.module('app', []).directive('ngModelOnblur', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elm, attr, ngModelCtrl) {
            if (attr.type === 'radio' || attr.type === 'checkbox') return;

            elm.unbind('input').unbind('keydown').unbind('change');
            elm.bind('blur', function() {
                scope.$apply(function() {
                    ngModelCtrl.$setViewValue(elm.val());
                });         
            });
        }
    };
});

这只是使用这里找到的建议https://groups.google.com/forum/?fromgroups#!searchin/angular/change$20blur/angular/LH0Q1A-qTVo/eyVIjJsFZGcJ

我创建了两个 jsFiddles,一个在这里使用 AngularJS 1.2.0-rc.2 ,另一个在这里使用AngularJS 1.2.0 。

ngModleOnBlur指令应从元素中删除'change'绑定<input>并添加显式'blur'绑定。

您会注意到小提琴的行为有所不同,例如绑定elm.bind('blur', function(){...})实际上并未正确绑定到元素,并且elm.unbind('input').unbind('keydown').unbind('change')在 1.2.0 中似乎不一样。

我知道新ng-blur指令,但在我的情况下,我不能直接使用它,而是需要手动覆盖绑定到元素的事件。如果有人可以发布一个关于如何手动覆盖绑定到元素的事件的工作 jsfiddle,和/或解释为什么它从 1.2.0-rc.2 更改为 1.2.0,那将非常有帮助。

4

2 回答 2

2

它与评估指令的顺序有关。

侦听 DOM 元素事件的输入指令实际上是在您的指令之后执行的。只需添加

priority: 1

到您的指令定义。输入指令的默认优先级为 0。

这是更新的小提琴

http://jsfiddle.net/yC627/

然而,奇怪的是文档明确指出

Directives with greater numerical priority are compiled first.

但是玩弄它,似乎恰恰相反。我不能告诉你为什么会这样。希望其他人可以插话。

编辑:我查看了更改日志,似乎来自此更改

https://github.com/angular/angular.js/blob/master/CHANGELOG.md#break-changes-1

确实应该更新文档以反映这一点。与预链接或编译函数相比,后链接函数以相反的优先级顺序解析。

于 2013-11-13T18:13:10.863 回答
0

我实现了分叉并更新您的小提琴以再次使用 1.2.0。这是你心目中的行为吗?http://jsfiddle.net/P2q6B/2/

    angular.module('app', []).directive('ngModelOnblur', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        priority: 99,
        link: function(scope, elm, attr, ngModel) {
            if(!ngModel) return; // do nothing if no ng-model
            if (['radio', 'checkbox'].indexOf(attr.type) > -1) return;

            elm.unbind('input').unbind('keydown').unbind('change');

            //ui->model
            elm.on('blur', function() {
                scope.$apply(read.call(this));         
            });

            function read() {
                ngModel.$setViewValue(elm.val());
            }
        }
    };
});

如果是这样,我解决这个问题的方法是阅读 angular.js 源代码,特别是搜索 contenteditable(大约第 16k 行;)

这个问题似乎是相关的: AngularJS - Create a directive that uses ng-model

于 2013-11-13T20:18:37.440 回答