I've written an AngularJS (1.x) directive that wraps a pure javascript library object, called browser
.
In order to update Angular scope variables and view in response to events, occurring within browser
, I have to manually call $apply
, invoking the digest loop:
scope.browser.on({
afterSetRange: function(){
if (!scope.$$phase) scope.$apply();
}
});
This works fine, when my directive is not creating its own scope
- I say scope: false
in Directive Definition Object (DDO). In that case scope
refers to the page controller's $scope
.
But when I'm using an isolated scope with scope: {myattr: '='}
, this apparently doesn't save me from getting:
Error: [$rootScope:inprog] $digest is already in progress
I solved this problem by replacing if (!scope.$$phase) scope.$apply
with $timout(angular.noop)
. (This means, that scope.$apply
is poorly designed - it should just work, instead of forcing people to dig in its internals). What I really want is an asnwer to the following theoretical question, not practical help:
I don't understand the theory behind $digest
loop. Documentation of rootScope.$new()
implies that $digest
event propagates from rootScope to its children. So, do we have a single digest loop for the whole angular app? Or a loop per each scope?
And how does Angular achieve synchronization between directive attributes and controller around it, when I'm using 2-way data binding in directive (e.g. scope: {myattr: '='}
)?