ng-model does not trigger change event

Marcus Krahl picture Marcus Krahl · Jul 31, 2014 · Viewed 18.1k times · Source

A framework I am using (jQuery Mobile) listens for the change event of textareas to change the markup. This is framework code so I cannot alter it and include the correct AngularJS functions.

I am binding the textarea to a scope variable via ng-model. When the scope variable changes (and thus the textarea content because it is bound) no javascript change event is fired. However without the change event jQuery Mobile cannot change the markup.

Is there a builtin way to let Angular trigger the change event without writing a directive? If I use a directive or ng-change I have to add the corresponding code to every occurrence of a textarea element.

Short example of what I am trying to do (also available as 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>

When the model updates, no change event is fired. If you type into the textarea and click outside (a basic textarea change), the change event fires.

Answer

Khanh TO picture Khanh TO · Aug 3, 2014

You could "override" your ngModel to trigger change event manually: 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
                }
            });
        }
      }
});

DEMO