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>

Spencer
  • 2,245
  • 3
  • 28
  • 50

1 Answers1

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.

Ahmad Baktash Hayeri
  • 5,802
  • 4
  • 30
  • 43
Esteban Felix
  • 1,561
  • 10
  • 21
  • I am needing your help. I want the data after binding, too. but i still get {{ xxxx.xxx }} in ng-repeat. any solutions? – chourn solidet Nov 10 '16 at 09:56
  • @chournsolidet Can you clarify? I'm unsure what you mean. – Esteban Felix Nov 11 '16 at 20:44
  • 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. – chourn solidet Nov 12 '16 at 02:17
  • by running your code, i still get this "
    content is {{content}}
    " in console log. All i want is "
    content is Hello, World!
    " in console log
    – chourn solidet Nov 12 '16 at 03:23