Reputation: 1929
I have a video player directive that uses an ng-src in its template. How do I run directive code after the ng-src has been evaluated so the video is actually loaded?
Here is the directive code:
return {
restrict: 'A',
replace: false,
transclude: false,
scope: true,
templateUrl: "/modules/didyouknow/views/slideshow-frame.directive.client.view.html",
link: {
pre: function() {
console.log('a');
},
post: function(scope, element, attrs) {
/**
* scope.frame - frame information
*/
scope.frame = scope[attrs.slideshowFrame];
}
}
};
both link functions execute before {{expr}}
has been evaluated in the template.
The whole point of post link is it that it's executed after child post-links, in reverse order as pre links. So why isn't it executing last? It executes immediately after the prelink function so why are they even separate functions?
Upvotes: 0
Views: 199
Reputation: 223104
There is a couple of recipes to execute the code in link
at the moment when directive DOM 'is there'. One is using zero-delayed timeout
$timeout(function () {
...
});
It is is generally preferable if you're after rendered DOM or interpolated values. It is not an option here, because templateUrl
is used and directive template is loaded asynchronously, and the template is not available during the linking phase.
Another recipe is using scope watchers/attribute observers (one-time if you don't care about data bindings).
var unobserveNgSrc = attrs.$observe('ngSrc', function (ngSrc, oldNgSrc) {
if (!ngSrc) return;
unobserveNgSrc();
...
})
It executes immediately after the prelink function so why are they even separate functions?
This behaviour suggests what it can be used for. In parent preLink
some things can be done that must precede child preLink
s or the latter could benefit from, which you will rarely find useful for simple directives. And parent postLink
executes last, and that's a good moment for 'ok, all of my children are already compiled and linked, let's do something at last'.
Upvotes: 0
Reputation: 136184
You could have $observe
inside your directive that will work same as that of the $watch
but the difference is it evaluates {{}}
interpolation expression.
Inside $observe
you could see if the ng-src
has value the only call the directive method. otherwise wait.
link: function(scope, element, attrs){
attrs.$observe('ngSrc', function(newVal, oldVal){
if(newValue){
//call desired code when `ng-src` have value
}
});
}
Upvotes: 1