gillyb
gillyb

Reputation: 8910

using $compile to create directive, and immediately get DOM properties

I created an angularjs directive that dynamically creates multiple directives, and puts them in a specific div on the DOM.
After each directive I create, I need to calculate the size of the wrapping div, to make an extra manipulation. I see that after calling $compile() to create the directives dynamically, they aren't in the DOM yet.

How can I force angularjs to update the DOM immediately after calling $compile() so that I can play with the DOM after that ?

Here's an example trying to show what I'm doing :

// This is my wrapping directive
angular.module('myModule').directive('wrapper', function($compile) {
    return {
        restrict: 'A',
        template: '<div></div>',
        scope: {
            // the scope here is a list of objects that are the models for the inner directives to be created
            innerModels: '='
        },
        link: function(scope, element, attrs) {
            for (var i=0; i<innerModels.length; i++) {
                var innerDirective = $compile('<inner-directive ng-model="innerModels['+i+']"></inner-directive>')(scope);
                element.append(innerDirective);

                // here I want to get the client size of the 'div' i created
                var divHeight = element[0].clientHeight;
                // divHeight == 0

                // but after the page loads
                // if i open the developer console when the page is finished loading, then the div does have a clientHeight value

            }
        }
    };
});

angular.module('myModule').directive('innerDirective', function() {
    return {
        restrict: 'E',
        template: '<span ng-bind-template="{{somethingFromModel}}"></span>',
        scope: {
            ngModel: '='
        },
        link: function(scope, element, attrs) {
            // some logic...
        }
    };
});

Note: I'm not using jQuery here (so I'd be happy if answers won't include jQuery solutions)

Upvotes: 2

Views: 140

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

Simple answer would be run your code in next digest cycle, that will ensure your element has been drawn on the DOM, You could do by using $timeout.

Code

    link: function(scope, element, attrs) {
        for (var i=0; i<innerModels.length; i++) {
            var innerDirective = $compile('<inner-directive ng-model="innerModels['+i+']"></inner-directive>')(scope);
            element.append(innerDirective);
        }

        // here I want to get the client size of the 'div' i created

        $timeout(function(){
           //here you will get update height.
           //play with rendered DOM here
        })

        // but after the page loads
        // if i open the developer console, then the div does have a clientHeight value
    }

Upvotes: 2

Related Questions