9

I have compiled an element using the $compile service. If I add that directly to the DOM, it looks great and all of the bindings are correct. If I want that element as a string though, it shows {{stuffHere}} instead of the bindings. Is there a way to get the html of the element after it's compiled?

$templateCache.put('template', '<div><div><div><span>content is {{content}}</span></div></div>   </div>');

$scope.content = 'Hello, World!';

var el = $compile($templateCache.get('template'))($scope);
$('body').append(el);

alert(el.html());

http://plnkr.co/edit/1sxvuyUZKbse862PieBa?p=preview

The element appended to the body shows content is Hello, World!

The alert shows <div><div><span ng-binding>{{content}}</span></div></div>

What I would like to see out of the alert is <div><div><span ng-binding>Hello World</span></div></div>

0

1 Answer 1

13

The issue is you're reading the contents of the element too early. If you add a $timeout to your read it will be correct:

angular.module('demo', []);
angular.module('demo').controller('PopoverDemoCtrl', function($scope, $timeout, $compile, $templateCache) {
  $templateCache.put('template', '<div><div><div><span>content is {{content}}</span></div></div></div>');

  $scope.content = 'Hello, World!';

  var el = $compile($templateCache.get('template'))($scope);
  $('body').append(el);
  $timeout(function() {
    console.log(el.html());
  }, 300);   // wait for a short while
});

Updated Plunker

Why is $timeout required?

After the $compile method is called it will not immediately take effect. This is due to the $digest cycle, since it uses the $scope it needs to run the $digest cycle to see if anything has affected $scope.content. This is why you have to set a $timeout, you need to wait until the $digest cycle completes before the element's content actually gets changed. You can read a bit more about how this all ties together here.

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

4 Comments

I am needing your help. I want the data after binding, too. but i still get {{ xxxx.xxx }} in ng-repeat. any solutions?
@chournsolidet Can you clarify? I'm unsure what you mean.
i have my template by getting from view. var table = document.getElementById('my-table').outerHTML; $templateCache.put('template', table); and i put everything like the answer above. The point is that when i have ng-repeat to loop my td of my table already in the view. then i just get my table by id. it doesn't give me the rendered table but with {{ xxxx.xxxx }} instead.
by running your code, i still get this " <div><div><span class="ng-binding">content is {{content}}</span></div></div> " in console log. All i want is " <div><div><span class="ng-binding">content is Hello, World! </span></div></div> " in console log

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.