lucuma
lucuma

Reputation: 18339

Watch not firing the second time the scope is changed in directive

I am animating a sprite in a directive and have a scope variable scope.isAnimating that is being watched. When the sprite is clicked the value is inverted and the animation stops/starts. The watch fires the first time the element is clicked and the value is changed but not the second time.

This is NOT the full directive but an abbreviated version. If you want to see this happening live click the sprite to stop and then click it again to start (won't work).

app.directive('sticker', function(timeFunctions){
return {
  restrict: 'AE',
  replace: true,

scope: {
  isAnimated: '=isanimated',
  Animation: '=animation',
  speed: '=speed'
},

 template: '<div></div>',
 link: function(scope, element, attrs) {

  scope.$watch('isAnimated', function(isAnimated) {
     // fires on the first click but not the second, breakpoint not hit
      if (scope.isAnimated) {
          startAnimation();
      } else {
         timeFunctions.$clearInterval( scope.animateTimeout );
      }
  });

   element.bind('click', function(e) {
      e.preventDefault();
      scope.isAnimated = !scope.isAnimated;
   });


  }
}
});

How can I make the watch work on both clicks?

Upvotes: 2

Views: 3408

Answers (1)

Alexander Puchkov
Alexander Puchkov

Reputation: 5973

You need to wrap modification of scope properties with $scope.$apply function. It doesn't currently work, because you modify scope from custom callback, outside of angular.

element.bind('click', function(e) {
    e.preventDefault();
    $scope.$apply(function () {
      scope.isAnimated = !scope.isAnimated;
    });
});

However, I would recommend you to use ng-click directive instead of manually binding to event. In this case you wouldn't need to wrap your code with $scope.$apply. Angular will do it for you inside ng-click.

Upvotes: 3

Related Questions