angularjs directive not working with dynamic content

Hello I have create an angular directive to add a bakcground and make it width equals to height(1:1) square div

app.directive('backImg', function($timeout){
return function(scope, element, attrs){
    $timeout(function(){
            var url = attrs.backImg;
            console.log(attrs);
            console.log("after printing attrs");
            if (url == null || url == ""){
                    url="/web/header.png";
            }
            element.css({
                    'height' :  element[0].offsetWidth,
                    'margin-bottom' : '20px',
                    'background-image': 'url(' + url +')',
                    'background-size' : 'cover',
                    'background-repeat': 'no-repeat',
                    'background-position': 'center center',
            });
    });
    };
});

This directive is working fine with the elements that appears when the page is first time loaded

....SOME HTML

 <div back-img="{{group.images[0].path}}"> </div> ---> Working fine

....MORE HTML

This time is not working, the only diference is that it been show if sessionSelected is true.

<div class="row" id="active-session" ng-show="userCtrl.sessionSelected">
    <div back-img="{{group.images[0].path}}"> </div> ---> Not working Working
</div>

Can you please help me figure this out, please

EDIT I looks like the directive is been called while it is not showed (ng-show) and for that reason group.images[0].path is null.

how can I do to call directive when visible??. I think it will be the way

Here you can see that the element is been populated with the correct img path when displayed

FIREFOX DEBUG

<div back-img="/web/uploads/56f7f53a2b82bbf75033559a/nKj0DMZrVt.jpeg"></div>

Answers 1

  • you are created the <div back-img="{{group.images[0].path}}"> and use the element[0].offsetWidth when the element is on display:none css (because of the ng-show=true attribute). so in order for this to work you need to change the ng-show to ng-if. that way when you change the flag to true it draw the html all over again and then this will call to the link function in the directive

    EDIT

    you can always use the $watch function that check for update in the url and when it occurs trigger the changes

    app.directive('backImg', function($timeout){
      return function(scope, element, attrs){
        scope.$watch(attrs.backImg,function(){
                var url = attrs.backImg;
                console.log(attrs);
                console.log("after printing attrs");
                if (url == null || url == ""){
                        url="/web/header.png";
                }
                element.css({
                        'height' :  element[0].offsetWidth,
                        'margin-bottom' : '20px',
                        'background-image': 'url(' + url +')',
                        'background-size' : 'cover',
                        'background-repeat': 'no-repeat',
                        'background-position': 'center center',
                })
            })
        };
    });
    

Related Articles