2

I want to compile an AngularJS template to plain text. I.e. I want to get what you would get by reading the inner HTML of a template rendered in the DOM on the page. But without actually rendering the template to the page.

I have tried using $compile like this

$compile(template)($scope).html()

But it does not seem to work as expected as demonstrated in this jsFiddle. The result both in the jsFiddle and in my project is nothing but a comment inserted by Angular.

What is the proper way to compile an Angular template and getting the result back as an HTML string?

In case anyone are curious why I need to do this: The rendered HTML will be sent to the backend which converts it to a pdf-file that is sent back again.

1
  • Have you tried innerhtml? Does $compile return a jQlite object? Commented Oct 23, 2013 at 13:26

2 Answers 2

2

If you want the final output with the scope applied to the view I believe you have to wait until the $digest call is completed.

I updated the fiddle to write the finished HTML to the console. I used a setTimeout() to wait until the $digest call was completed and it displayed the actual result that would be displayed in the HTML.

fiddle

Sign up to request clarification or add additional context in comments.

3 Comments

I didn't know about $digest. Your solution does indeed work but it is kinda a hack. I can't assume that the compile will always happen in under a second.
I was using the setTimeout to demonstrate that if you hold onto the element until after the $digest is completed that the element will be rendered regardless of if it is in the DOM or not. You can call $scope.$apply(); directly and you can get the html that way. You will see an error in the log as well, but it isn't fatal. I updated the fiddle to do this.
+1. Andy's solution is correct given this use case. But shouldn't trigger digest loop directly, should just use setTimeout(..., 0) to avoid 2 digest loops (one in code & one by AngularJS after bootstrap).
0

Something like this ought to do. The isolated scope is optional I suppose, but any model you have will need to be a part of a Scope:

var template = '<div ng-repeat="item in items">{{item}}</div>',
    element = angular.element(template ),
    scope = $rootScope.$new(true); //isolated scope

scope.items = ['foo', 'bar', 'frob'];

// apply bindings!
$compile(template)(scope);

var html = template[0].outerHTML;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.