Reputation: 2182
You can see the problem in this plunk with Chrome or FireFox's console open:
http://plnkr.co/edit/jmDcxqQ48PmeHt3EPVMU
When you click "Push!" for the first time, the watch function doesn't execute. But if you push it again, it does execute. It's like it ignores the first push. However, you can clearly see the dataPoints array changes after the first push due to the timeout function that is executing in the background. What's weirder, is if you comment out the jQuery fadeIn wrapper, the code works as expected (the watch function is executed on the first button push).
What's going on here? Why is the $watch function not executing when jQuery().fadeIn is used?
Upvotes: 0
Views: 993
Reputation: 364727
jQuery('#mytest').fadeIn(200, function() {
$scope.mydata.dataPoints.push(1);
$scope.$$phase || $scope.$apply();
})
When the fadeIn callback runs, it runs "outside" Angular, so we need to call $scope.$apply()
to run a digest cycle. However, if the object is already visible, it seems that jQuery runs the callback immediately (so we're still "inside" Angular), so we don't need to (and shouldn't) call $scope.$apply()
.
The easy way to handle both cases is to check to see if we are already in a digest cycle using private property $$phase
. A cleaner implementation would be to not call fadeIn()
if the div is already visible.
Upvotes: 2