ng-ampere-debounce, кажется, перестает работать в AngularJS 1.2

Я использовал директиву jQuery/AngularJS для устранения дребезга входных данных в приложении, поддерживаемом Firebase. Это пришло из сообщения Ларса Герсманна и отлично работало:

http://orangevolt.blogspot.com.au/2013/08/debounced-throttled-model-updates-for.html

Обновление с Angular 1.0.8 до 1.2, кажется, ломает ситуацию. Каждый раз, когда срабатывает директива, вместо того, чтобы извлекать события из элемента, функция $._data возвращает неопределенное значение, что приводит к этой ошибке:

TypeError: Object.keys вызывается для не-объекта в Function.keys (собственный)

Здесь определено:

 var map = $._data( element[0], 'events'),
 events = $.each( Object.keys( map), function( index, eventName) {
    // map is undefined :(
    ...
 }

Изменилось ли что-то в AngularJS или даже в jQuery, что не будет тянуть события этого элемента, как раньше?

(Примечание: я использую jQuery версии 1.8.3, которая не изменилась при обновлении Angular).

Спасибо всем, кто может пролить свет на это!


person murraybunton    schedule 18.11.2013    source источник
comment
Кажется, есть две вещи, которые могут быть проблематичными. Во-первых, AngularJS заблокирован вызывает события таким образом: И есть также некоторые люди работа с приоритетами, чтобы активировать следующие типы слушателей:   -  person murraybunton    schedule 20.11.2013


Ответы (1)


Вместо этого вы можете получить доступ к этим событиям, используя unbinds, binds и метод Angular $timeout для создания более простого сценария устранения отказов. Это основано на этом сообщении о блокировании ngChange событий.

Это переписанная директива debounce, которая работает в Angular 1.2. Он отменяет привязку ввода, а затем применяет изменения с помощью $setViewValue после задержки в 1000 мс. Я также добавил мгновенное изменение размытия. Ключом к тому, чтобы заставить эту работу работать над исходным постом, была установка приоритета.

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

        elm.unbind('input');

        var debounce;
        elm.bind('input', function() {
            $timeout.cancel(debounce);
            debounce = $timeout( function() {
                scope.$apply(function() {
                    ngModelCtrl.$setViewValue(elm.val());
                });
            }, 1000);
        });
        elm.bind('blur', function() {
            scope.$apply(function() {
                ngModelCtrl.$setViewValue(elm.val());
            });
        });
    }

}
});

Плюс демонстрация JSFiddle

person Tom Maitland    schedule 20.11.2013
comment
Вы только что сделали мой день. Спасибо. - person jessegavin; 16.12.2013