ng-модель не вызывает событие изменения

Используемая мной структура (jQuery Mobile) прослушивает событие изменения текстовых полей для изменения разметки. Это код фреймворка, поэтому я не могу его изменить и включить правильные функции AngularJS.

Я привязываю текстовое поле к переменной области через ng-model. Когда переменная области видимости изменяется (и, следовательно, содержимое текстовой области, потому что оно связано), событие изменения javascript не запускается. Однако без события изменения jQuery Mobile не может изменить разметку.

Есть ли встроенный способ позволить Angular инициировать событие изменения без написания директивы? Если я использую директиву или ng-change, я должен добавить соответствующий код к каждому вхождению элемента textarea.

Краткий пример того, что я пытаюсь сделать (также доступен как jsFiddle):

<div ng-app="app" ng-controller="Controller">
    <textarea ng-model="textValue"></textarea>
</div>

<script type="text/javascript>
var module = angular.module("app",[]);

module.controller("Controller", function ($scope) {
   $scope.textValue = "Test"; 

   window.setInterval(function () {
       $scope.textValue = $scope.textValue === "Test" ? "Hello World" : "Test";
       $scope.$apply();
   },2000);
});

//Dummy framework code which I do not have access to
document.querySelector("textarea").addEventListener("change", function () {
  alert("changed");
});
</script>

Когда модель обновляется, событие изменения не запускается. Если вы вводите текстовое поле и щелкаете снаружи (базовое изменение текстового поля), срабатывает событие изменения.


person Marcus Krahl    schedule 31.07.2014    source источник
comment
addEventListener является родным, а не jquery. Кроме того, ng-модель переопределяет событие изменения, особенно если событие изменения является родным и не обрабатывается angular.   -  person Luis Masuelli    schedule 31.07.2014
comment
Не уверен, что вы пытаетесь сделать.   -  person zs2020    schedule 31.07.2014
comment
Немного по теме, но могу ли я дать несколько советов. Если все возможно, не следует сочетать jQuery Mobile и AngularJS, они не очень хорошо работают вместе. Я думаю, что у вас будет много головной боли, пытаясь выполнить это, я говорю по опыту.   -  person Jared Reeves    schedule 31.07.2014
comment
Ограничения проекта требуют комбинации JQM и AngularJS, которая до сих пор работала достаточно хорошо. Я искал только какой-то волшебный переключатель, который включает распространение события изменения. Кажется, что этого переключателя не существует.   -  person Marcus Krahl    schedule 01.08.2014


Ответы (3)


Вы можете "переопределить" свой ngModel, чтобы инициировать событие изменения вручную: AngularJS — как переопределить директиву ngClick

module.directive("ngModel",function(){
    return {
        restrict: 'A',
        priority: -1, // give it lower priority than built-in ng-model
        link: function(scope, element, attr) {
            scope.$watch(attr.ngModel,function(value){
                if (value){
                    element[0].onchange();
               //   element.trigger("change"); use this for jQuery
                }
            });
        }
      }
});

ДЕМО

person Khanh TO    schedule 03.08.2014
comment
Пожалуйста, проверьте вашу консоль, я не использую alert - person Khanh TO; 03.08.2014
comment
Это именно то, что я искал, потому что он добавляет правильное поведение, не касаясь всех частей кода. - person Marcus Krahl; 04.08.2014
comment
Обратите внимание, что запуск события может привести к потенциальным проблемам с $digest цикл... и некромантия - person Patrick Barr; 11.07.2017
comment
Крошечный вопрос: это директива, которая разделяет родительскую область, и мы добавляем часы. Если в HTML-объявлении этой директивы есть ngIf, что приводит к ее удалению и повторному добавлению несколько раз, не приведет ли это к утечке данных? Как-то можно справиться с этим? Насколько я знаю, директивных дескрукторов нет... - person user2173353; 28.08.2017
comment
@ user2173353: Думаю, проблем нет. NgIf (docs.angularjs.org/api/ng/directive/ngIf) директива имеет приоритет: 600, которая выполняется перед нашей директивой NgModel (приоритет: -1). Это означает, что обработчик привязан к области действия, созданной ngIf. Если ngIf удаляет область действия, обработчик также уничтожается, поскольку он напрямую связан с областью действия. - person Khanh TO; 01.09.2017

почему ты не используешь ng-change

<div ng-app="app" ng-controller="Controller">
    <textarea ng-model="textValue" ng-change="changed()"></textarea>
</div>

также используйте $ интервал

module.controller("Controller", function ($scope) {
   $scope.textValue = "Test"; 

   var interval = $interval(function () {
       $scope.textValue = $scope.textValue === "Test" ? "Hello World" : "Test";
   },2000);

   $scope.changed = function(){
         alert('changed');
   }

   $scope.$on("$destroy", function(){
       $interval.cancel(interval)
   })
});
person harishr    schedule 31.07.2014
comment
Я не использую ng-change, потому что сам jQuery Mobile прослушивает событие изменения (это код фреймворка). Всегда есть возможность сделать это угловым способом, но, к сожалению, jQuery Mobile не делает этого таким образом. - person Marcus Krahl; 01.08.2014
comment
но не может ли быть два листнера для события click ?? - person harishr; 01.08.2014
comment
Какое событие клика? Прослушиватель событий для события изменения связан с jQuery Mobile. - person Marcus Krahl; 01.08.2014
comment
Обработчик события изменения определяется jQuery Mobile. Я не могу использовать ng-change, потому что я не хочу привязывать другой обработчик изменений, а вместо этого запускаю существующий обработчик изменений. Вот почему ваш ответ, хотя и хорошо написанный, не подходит для вопроса - person Marcus Krahl; 01.08.2014

addEventListener является родным, а не jquery. Кроме того, ng-модель переопределяет событие изменения, особенно если событие изменения является родным.

Если вы хотите использовать ngModel, а также прослушивать события изменений, используйте: https://docs.angularjs.org/api/ng/directive/ngChange (будьте осторожны: эта директива ТРЕБУЕТ ngModel)

person Luis Masuelli    schedule 31.07.2014