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>
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.