AngularJS 1.2.0-rc.2 vs 1.2.0 привязка элементов

Я недавно обновил свой AngularJS Framework с версии 1.2.0-rc.2 до версии 1.2.0 и натолкнулся на странную проблему, с которой я не разобрался. Проблема, которую я ранее решил, заключалась в том, чтобы принудительно вызывать поле ввода для события размытия вместо события изменения. Код для директивы, которую я первоначально использовал, был:

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, это было бы невероятно полезно.

2 ответа

Решение

Это связано с тем, что директивы оцениваются.

Директива input, которая прослушивает события элемента 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#breaking-changes-1

Документация должна быть действительно обновлена, чтобы отразить это. Функции после ссылки разрешаются в обратном порядке приоритетов по сравнению с функциями предварительной ссылки или компиляции.

Я добился того, чтобы снова раскрутить и обновить скрипку для работы с 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 - создайте директиву, которая использует ng-модель

Другие вопросы по тегам