简体   繁体   中英

How to watch for a property change in a directive

I have an angular directive (with isolate scope) set up like this

<div ng="$last" somedirective datajson=mydata myprop="{{ mydata.myspecialprop }}"></div>

(which actually gets rendered multiple times because it's inside an ng-repeat.)

Following the instructions of this SO answer , I tried to observe myprop for changes in the directive, however, the code inside the $scope.watch never runs even when the property changes (on a click event). I also tried scope.$watch(attrs.myprop, function(a,b){...) and it never ran either. How do I watch for the change in myprop

myapp.directive('somedirective', function () {
  return {
    restrict: 'AE',
    scope: {
      datajson: '=',
      myprop: '@'
    },
    link: function (scope, elem, attrs) {
      scope.$watch(scope.myprop, function (a, b) {
        if (a != b) {
          console.log("doesn't get called when a not equal b");
        } else {

        }
      });
    }
  };
}

Update: the click event that changes the property is handle in the controller and I'm guessing this isn't reflected back in the isolate scope directive so that $watch is never getting triggered. Is there a way to handle that?

When you use an interpolation binding ( @ ) you cannot use scope.$watch , which is reserved for two-way bindings ( = ) or internal scope properties.

Instead, you need to use attrs.$observe which does a similar job:

link: function(scope, elem, attrs){
   attrs.$observe('myprop', function(newVal, oldVal) {
     // For debug purposes
     console.log('new', newVal, 'old', oldVal);
     if (newVal != oldVal){
          console.log("doesn't get called when newVal not equal oldVal");
      } else {
          // ...
     } 
   });
 }

Also, everytime myprop change, the newVal will be different from its oldVal , so it is a bit weird that you skip that case which is the only one which will happen.

NOTE: you also forgot doublequotes for the datajson two-way binding: datajson="mydata"

Intead of passing a string, try it as variable

scope: {
     datajson: '=',
     myprop: '=' //change to equal so you can watch it (it has more sense i think)
  }

then change html, removing braces from mydata.myspecialprop

<div ng="$last" somedirective datajson="mydata" myprop="mydata.myspecialprop"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM