Reputation: 55779
If I invoke $scope.$apply()
ten times in immediate succession I presume ten root scope digests will occur.
Can we say that if the call to $scope.$apply()
was debounced so that the trailing call was always completed that the final state of the application would be the same as if the debounce was not in effect?
Can we say anything about the duration of successive root scope digests, given that a previous digest has just completed?
Edit:
I would like to clarify the purpose of my question.
Say I have a controller MyController
, with an instance instantiated for each instance of a directive MyDirective
.
These controller instances listen for an event my-event
and trigger a root-scope digest each time my-event
is raised.
Ten instances of MyDirective
are rendered to the UI via an ng-repeat
.
Another component raises an event my-event
. Each of the ten MyController
instances then trigger a root-scope digest.
If we put the sanity of this state of affairs to one side, my question is this: if I debounce the root-scope digest attempts made by MyController
, and ensure that the trailing attempt always gets invoked, is the correctness of the program maintained?
var service = require('my-service');
function MyController($scope) {
this._$scope = $scope;
myService.on('my-event', this.triggerRootScopeDigest.bind(this));
}
MyController.prototype.triggerRootScopeDigest = function() {
this._$scope.apply();
}
Upvotes: 1
Views: 378
Reputation: 4481
The edited question still points to $applyAsync
or $evalAsync
as your solution.
Here's an example fiddle comparing both $apply()
and $applyAsync()
:
http://jsfiddle.net/635pvkkt/
You'll notice that 10 items are added via ngRepeat
, each watching an doApply
event, and an doApplyAsync
event, to trigger the respective functions.
When you click the button that broadcasts the doApply
, it triggers 10 $digest
calls, each doing the directives work (in this case, as simple console.log
).
The doApplyAsync
broadcast, however, causes all 10 directives to do their work in a single $digest
.
Of course, a debounced callback would also work. You could pass each directive a reference to a debounced function that is attached to a parent Controller's scope. If that debounce function works correctly and has a long enough debounce-time, it will only apply once. In some situations that's preferred, but the original question feels simple enough (assuming triggering a $digest
is the main goal of the event) that substituting $apply
for $applyAsync
(or $evalAsync
, depending on the semantics) seems more appropriate.
EDIT: Though the results are the exact same, this fiddle is more accurate as it triggers real DOM events on the elements directly: http://jsfiddle.net/uh9wxxho/
Upvotes: 1