Search code examples
javascriptangularjsangularjs-ng-repeatangular-directiveangular-directive-link

custom directive's link function is invoked before ng-repeat is replcaed


I have the following directive:

.directive("picSwitcher", ["$timeout", function($timeout){
return {
    restrict: "A",
    scope: {
        pics: "=",
        fadeTime: "@",
        timeForPic:"@"
    },
    template: '<img ng-repeat="pic in pics" src="{{pic.url}}" style="display: none"/>',
    link:   function ($scope, element){
                //some code...
                $(element.find("img")[0]).css({display: "block"});
            }
};
}])

my problem is, when my link function is invoked - ng repeat is yet to "compile" (what word should be used here instead of compiled?)

so I am trying to set css of undefined.. how can I force the link function to run after ng-repeat finished?!

for now I am solving this by replacing $(element.find("img")[0]).css({display: "block"}); with $timeout(function(){ $(element.find("img")[0]).css({display: "block"});}, 200);

but that feels 'hacky'

is there something I am missing to achieve my goal in an easier way? in general, what is the best way to manipulate ng-repeat dom element inside the link function of a custom directive?

Thanks, Jimmy.


Solution

  • you can check $scope.$evalAsync

    $scope.$evalAsync(function(){
        $(element.find("img")[0]).css({display: "block"});
    }
    

    This will make the function executed after the dom rendering.

    Also, using $timeout is not a bad idea if u set the delay to 0

    $timeout(function(){
        $(element.find("img")[0]).css({display: "block"});}, 
    0);
    

    will also do the trick i think.

    More reference http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm