2013-11-18 1 views
2

Я использую директиву jQuery/AngularJS для отладки входов в приложении с поддержкой Firebase. Он пришел с поста Lars Gersmann, и работал великий:ng-ampere-debounce, похоже, перестает работать в AngularJS 1.2

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

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

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

он определяется здесь:

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

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

(Обратите внимание, что я использую jQuery версии 1.8.3, которая не изменилась в Угловом апгрейде).

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

+0

Кажется, что есть две вещи, которые были бы проблематичными. Во-первых, [AngularJS заблокирован] (http://docs.angularjs.org/guide/migration#interpolations-inside-dom-event-handlers-are-now-disallowed) вызывает события таким образом: И есть также некоторые люди [занимаются приоритетами] (http://stackoverflow.com/questions/19960958/angularjs-1-2-0-rc-2-vs-1-2-0-element-binding), чтобы получить таких слушателей стрелять: – murraybunton

ответ

6

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

Это переписанная директива об отклонении, которая, похоже, работает в 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()); 
      }); 
     }); 
    } 

} 
}); 

Plus JSFiddle Demo

+0

Вы только что сделали свой день. Спасибо. – jessegavin

Смежные вопросы