heinob
heinob

Reputation: 19464

Compile angular directive template without dom

Is it possible to get the compiled angular directive html-code without the dom?

This is what I want:

var scope = {
        list: ["Peter","Paul","Mary"]
    },
    template = '<ul><li ng-repeat="item in list"{{item}}</li><ul>',
    result;

result = desiredFunction( scope, template );

// result should be: "<ul><li>Peter</li><li>Paul</li><li>Mary</li></ul>"

Is there a possibility to get the desiredFunction?

EDIT:

To make my wish a little bit clearer: I want to "compile" an angular directive template string without having to push the directive into the dom, because I do not want to have it in the dom. I even do not want a directive anyway. What I only want is the compiled string from a template string ( template-string + scope-object ==> html-string).

Is there any Angular-internal or even external (library) way to do this?

EDIT (2):

Taking NewDev's answer, correcting my html template and adding a $timeout leads me to the following solution, which works:

    $scope.list = ["Peter", "Paul", "Mary"];
    var template = '<ul><li ng-repeat="item in list">{{item}}</li></ul>';
    var jqElem = angular.element(template);
    $compile(jqElem)($scope);
    $timeout( function() {
        console.log( jqElem.html() );
    });

EDIT (3):

Following zerflagL's comment this is also possible (and even shorter):

    $scope.list = ["Peter", "Paul", "Mary"];
    var template = '<ul><li ng-repeat="item in list">{{item}}</li></ul>';
    var result = $compile(template)($scope)[0];
    $timeout( function() {
        console.log( result );
    });

Upvotes: 1

Views: 1015

Answers (2)

user13989141
user13989141

Reputation: 1

In case if don't need directive interpretation: Use $interpolate. Then don't need $compile and $scope. Related: Compile a template without passing scope

var html = '<div> {{item}} </div>' // or $templateCache.get('myTemplate.html') too
var vars = { item: 'John' };
var result = $interpolate(html)(vars);
// result = '<div> John </div>'

Upvotes: 0

New Dev
New Dev

Reputation: 49590

You can compile without the element being in the DOM.

Assuming you have proper injections, you could do:

var template = '<ul><li ng-repeat="item in list"{{item}}</li><ul>';
var jqElem = angular.element("<div>").html(template);
$compile(jqElem)($scope);

At this point, however, the innerHTML is still not compiled. For that, we need to wait until the end of $digest cycle. One way I know how to do this is to use $timeout, but that means that your function would have to return a promise

return $timeout(function(){ return jqElem.html(); }, 0);

P.S.

You could pass template directly into the $compile function, but note that .html() will return inner HTML, so you may need to do something like the following to get the full template:

return $timeout(function(){ return jqElem[0].outerHTML; }, 0);

Upvotes: 4

Related Questions