Question

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.

Was it helpful?

Solution

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

OTHER TIPS

why dont you use ng-change

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

also use $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)
   })
});

The addEventListener is native, not a jquery one. Also, the ng-model overrides the change event, specially if the change event is native.

If you want to use ngModel and also listen the change events, use: https://docs.angularjs.org/api/ng/directive/ngChange (be careful: this directive REQUIRES ngModel)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top