ng-model不会触发change事件

5
我正在使用的框架(jQuery Mobile)监听文本区域的更改事件以更改标记。这是框架代码,因此我无法更改它并包含正确的AngularJS函数。
我通过ng-model将文本区域绑定到作用域变量。当作用域变量更改(因此文本区域内容也会更改,因为它已绑定),没有触发任何JavaScript更改事件。但是,如果没有更改事件,jQuery Mobile无法更改标记。
是否有内置方法可以让Angular触发更改事件而无需编写指令?如果我使用指令或ng-change,则必须将相应的代码添加到每个文本区域元素的出现中。
我尝试做的简短示例(也可在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>

当模型更新时,不会触发任何更改事件。如果您在文本区域中输入并单击外部(基本文本区域更改),则会触发更改事件。


1
addEventListener 是原生的,不是 jQuery 的。此外,ng-model 会覆盖 change 事件,特别是如果 change 事件是原生的且未被 Angular 处理。 - Luis Masuelli
不确定你想要做什么。 - zs2020
有点跑题,但我能给你一些建议吗?如果可能的话,你不应该将jQuery Mobile和AngularJS结合在一起,它们之间并不兼容。我认为你会在尝试实现这个目标时遇到很多问题,我是从经验中说出来的。 - Jared Reeves
项目的限制要求结合使用JQM和AngularJS,到目前为止效果还不错。我只是在寻找一些“魔法”开关,以启用更改事件传播。但是似乎并不存在这样的开关。 - Marcus Krahl
3个回答

11

您可以"覆盖"您的ngModel以手动触发更改事件:AngularJS - how to override directive 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
                }
            });
        }
      }
});

演示


请检查您的控制台,我不使用 alert - Khanh TO
这正是我想要的,因为它可以添加正确的行为而不用触及代码的所有部分。 - Marcus Krahl
请注意,触发事件可能会导致潜在的$digest循环问题...和死灵术。 - Patrick Barr
这里有一个小问题:这是一个共享父级作用域的指令,我们正在添加一个监视器。如果在该指令的HTML声明中有ngIf导致它被多次删除和重新添加,那么这不会创建一个监视器泄漏吗?有没有办法处理这个问题?据我所知,没有指令解构函数... - user2173353
1
@user2173353:我认为没有问题。NgIf(https://docs.angularjs.org/api/ng/directive/ngIf)指令的优先级是600,比“我们”的`NgModel`(优先级:-1)更高。这意味着处理程序附加到由`ngIf`创建的作用域上。如果`ngIf`删除了该作用域,则处理程序也会被销毁,因为它直接附加到该作用域上。 - Khanh TO

3
为什么不使用ng-change?
<div ng-app="app" ng-controller="Controller">
    <textarea ng-model="textValue" ng-change="changed()"></textarea>
</div>

还要使用 $interval

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)
   })
});

我不使用ng-change,因为jQuery Mobile本身正在侦听更改事件(这是框架代码)。总是有“以Angular方式”完成的选项,但不幸的是,jQuery Mobile没有按照这种方式进行操作。 - Marcus Krahl
但是点击事件不能有两个监听器吗? - harishr
什么是点击事件?更改事件的事件监听器由jQuery Mobile绑定。 - Marcus Krahl
改变事件处理程序由jQuery Mobile定义。我不能使用ng-change,因为我不想绑定另一个更改处理程序,而是触发现有的更改处理程序。这就是为什么你的答案虽然写得很好,但并不适合这个问题的原因。 - Marcus Krahl

0

addEventListener是原生的,不是jQuery的。此外,ng-model会覆盖change事件,特别是如果change事件是原生的。

如果您想使用ngModel并同时监听更改事件,请使用:https://docs.angularjs.org/api/ng/directive/ngChange(注意:此指令需要ngModel)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接