I have a legacy application that contains some content inserted into the DOM through jQuery. I would like the legacy parts of the codebase to be responsible for compiling the html that it inserts into the DOM.
I can get it to compile the original html using $compile
, but any DOM elements added by the directive template or templateUrl are not compiled unless I call $scope.$apply()
from the directive itself.
What am I doing wrong here?
Link to the violin: http://jsfiddle.net/f3dkp291/15/ p>
index.html
<div ng-app="app"> <debug source='html'></debug> <div id="target"></div> </div>
application.js
angular.module('app', []).directive('debug', function() { return { restrict: 'E', template: "scope {{$id}} loaded from {{source}}", link: function($scope, el, attrs) { $scope.source = attrs.source if( attrs.autoApply ) { // this works $scope.$apply() } }, scope: true } }) // mimic an xhr request setTimeout(function() { var html = "<div><debug source='xhr (auto-applied)' auto-apply='1'></debug><br /><debug source='xhr'></debug></div>", target = document.getElementById('target'), $injector = angular.injector(['ng','app']), $compile = $injector.get('$compile'), $rootScope = $injector.get('$rootScope'), $scope = angular.element(target).scope(); target.innerHTML = $compile(html)($scope)[0].outerHTML // these do nothing, and I want to compile the directive template from here. $scope.$apply() $scope.$root.$apply() angular.injector(['ng','app']).get('$rootScope').$apply() }, 0)
Output
scope 003 loaded from html scope 005 loaded from xhr (auto-applied) scope {{$id}} loaded from {{source}}
Update: the solution works for directives with the template property, but not with the Url template
So, I had to compile dom nodes, not an HTML string. However, this updated script shows the same failure behavior if the directive contains templateUrl:
http://jsfiddle.net/trz80n9y/3/