Search code examples
javascriptangularjsangularjs-directiveangular-directive

How can I listen an element's attribute change in an Angular directive?


here's a plunker, it pretty well exposes what I'm trying to do.

I have a directive with ! isolated scope ! with an attribute that is intended to be changed

<div ng-init="environment='natural'">
  <input ng-model=environment>
  <chameleon env="{{ environment }}"></chameleon>
</div>

I want my directive to response to global scope's changes :

angular.module('app', []).directive('chameleon', function () { return {

  template: 'I am {{ color }}',
  scope: {} // isolated

  ,link: function (scope, element, attrs) {

    scope.$watch('env', function () {
       scope.color = getColor();
    });

    function getColor () {
       switch (attrs.env) {
          case 'excited': return 'red';
          ...
          case 'natural':
          default: return 'green';
       }
    }

        /* here I need something similar to this not-working code :
         *   element.on('attributeChange', function () {
         *      scope.env = attrs.env
         *   });
         */
  }

}});

I know I can use the isolated scope to bind values of the surrounding scope, like

scope: {
  env: '='
}

but I really need to have an independent component as the value of the attribute env is not only going to be changed from the model.

feel free to fork my plunker.


Solution

  • You need to use attrs.$observe that will work as the same as $watch. It works on {{}} value & change in value will call the $observe function.

    Code

    attrs.$observe('env', function() {
         scope.color = getColor();
    });
    

    Demo Plunkr