In the above case, I'm expecting elements with cls
class to be picked up with the same behavior from within ng-repeat
(ng-bind-html-unsafe
), and explicitly set one.
<div ng-app="appp">
<div ng-controller="Ctrl">
<ul>
<li ng-repeat="r in data" ng-bind-html-unsafe="r.alink"></li>
</ul>
<div class="cls">External</div>
</div>
</div>
function Ctrl($scope) {
$scope.data = [
{alink: '<span><a class="cls">One</a></span>'},
{alink: '<span><a class="cls">Two</a></span>'}
];
}
angular.module('appp', [])
.directive('cls', function() {
return {
restrict: 'C',
replace: true,
scope: true,
link: function(scope, element, attrs) {
element.bind('click', function() {
alert('Aha!');
});
}
}
});
I'm wondering what I'm doing wrong here?
The problem is that the new HTML is not being compiled by Angular. The simplest solution may be to manually compile the dynamic content using the $compile
service. Do this in a custom directive and replace ng-bind-html-unsafe="r.alink"
with something like htmlinsert="r.alink"
. Here is how that directive could be coded:
angular.module('appp', [])
.directive('htmlinsert',function($compile){
return {
scope: {
htmlinsert: '='
},
link: function(scope,element,attrs){
var compiledElement = $compile(scope.htmlinsert)(scope);
element.append(compiledElement);
}
}
});
The reference to the html string is passed using isolate scope binding, and is then compiled before being appended to the current iteration of the repeated DOM element.