Reputation: 178
Like the headline says, I don't understand why I need a $timeout when manipulating the DOM inside a directive's link function.
The code below works. The element in question is a 1x1 div that holds a container for a video plugin. If I remove the $timeout, the element is not resized and is not visible. Removing the $timeout and replacing it with $rootScope.$apply() does not work. There is no ajax calls being waited on. I simply want to resize an element on a user action.
My problem is that the timeout time is really arbitrary and on older browsers running on older computers I need a bigger timeout value in the range of 1500ms, which works about 90% of the time. Even 1500ms is ridiculous and I certainly don't want to make it greater.
var containerBoundingBox;
$timeout(function () {
containerBoundingBox = element[0].getBoundingClientRect();
$log.warn('containerBoundingBox: ', containerBoundingBox);
getActiveVideoElement().css({
'position': 'fixed',
'z-index': 1000000,
'top': containerBoundingBox.top + 'px',
'left': containerBoundingBox.left + 'px',
'width': containerBoundingBox.width + 'px',
'height': containerBoundingBox.height + 'px'
});
}, 100);
The element code, taken from a live page: It is the div I'm resizing not the object tag.
<div id="pluginContainer"
class="pluginContainer ng-scope ng-isolate-scope"
style="position: fixed; top: 1px; left: 1px; width: 1px; height: 1px; z-index: 1000000;">
<object type="application/x-xxxx"
id="xxxxxPlugin"
style="width: 100%; height: 100%;"
></object>
</div>
Upvotes: 1
Views: 899
Reputation: 787
The timeout is required to allow the DOM manipulation from the last angularjs digest cycle to complete. Without this you won't see any changes in height, text, style, class, etc.
Also, if you don't include a time after the timeout, the timeout will occur immediately after the digest completes. There was one case were we needed access outside of this and used an undocumented feature $$postDigest, this allowed us to gather data from the digest without including browser events.
Upvotes: 3
Reputation: 9284
In angular there are digest cycles which are usually caused by DOM manipulation that is annotated with bindings which are causing the page/part of the page to redraw. When you perform an operation which is not related to the internal mechanism of angular then the framework does not know that a digest cycle should be initiated and therefore you need sometimes to tell it explicitly to do so.
Upvotes: 0