Reputation: 61
I am working with ionic 3. So I have this code on controller and it works
$scope.note = 'Lorem...';
$rootScope.$on('Active',function() {
$timeout(function() {
$scope.note = 'test';
},0);
});
But why this not work?
$scope.note = 'Lorem...';
$rootScope.$on('Active',function() {
$scope.note = 'test';
});
What is the best approach for this?
Upvotes: 0
Views: 566
Reputation: 222474
In this context it can be considered a bad practice. Spontaneous use of $timeout
usually indicates that a developer doesn't know if the code runs inside or outside of digest cycle and tries to play it safe.
The explantion why this doesn't work stays outside of the scope of posted code, but the reason is that this code runs outside of a digest. This depends on where Active
scope event is triggered, and this is what a developer should care about in the first place, since scope events don't necessarily happen inside of digest cycle.
If the event is known to happen outside of a digest, digest-dependent code should be wrapped with $apply
:
$scope.$on('Active',function() {
$scope.$apply(function() {
$scope.note = 'test';
});
});
If the event is known to happen both inside and outside of a digest, code should be wrapped with $evalAsync
:
$scope.$on('Active',function() {
$scope.$evalAsync(function() {
$scope.note = 'test';
});
});
$timeout(...)
is supposed to be used only when it's behaviour is wanted, i.e. one tick delay or more and a digest.
As it was suggested by @georgeawg, it is also a bad practice to use $rootScope
as global event bus in controllers (they have access to child scopes). This is basically an antipattern that may cause memory leaks. Considering that an event was $broadcast
ed, it will propagate to child scopes. As a rule of thumb, it should be $scope.$on(...)
, unless there are reasons why it should be done on $rootScope
specifically.
Upvotes: 1
Reputation: 598
This happens when the view does not get notified of a change in controller. It usually happens for ng-repeat arrays/objects or inside the forms that do not use a global object. The $timeout solution works or you can call $scope.$apply(). Please look at this document for more information:
https://www.sitepoint.com/understanding-angulars-apply-digest/
Upvotes: 0