If I have a directive that responds to the status of a particular attribute on the scope, and I want to change that attribute in my test and verify that it responds correctly, which is the best way of doing that change?
I've seen both these patterns:
scope.$apply(function() { scope.myAttribute = true; });
and
scope.myAttribute = true; scope.$digest();
What is the difference between them, and which is better and why?
$apply() function will execute custom code and then it will call $scope. $digest() function forcefully to check all watch list variables and update variable values in view if any changes found for watch list variables. In most of the time angularjs will use $scope.
In AngularJS, $apply() function is used to evaluate expressions outside of the AngularJS context (browser DOM Events, XHR). Moreover, $apply has $digest under its hood, which is ultimately called whenever $apply() is called to update the data bindings. We will take an example to give a better understanding.
scope.$digest()
will fire watchers on the current scope, and on all of its children, too. scope.$apply
will evaluate passed function and run $rootScope.$digest()
.
The first one is faster, as it needs to evaluate watchers for current scope and its children. The second one is slower, as it needs to evaluate watchers for$rootScope
and all it's child scopes.
When an error occurs in one of the watchers and you use scope.$digest
, it's not handled via $exceptionHandler
service, so you need to handle exception yourself. scope.$apply
uses a try-catch
block internally and passes all exceptions to $exceptionHandler
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With