Reputation: 191
I'm injecting insecure html into some <div>
, like this:
<div class="category-wrapper" ng-bind-html="content"></div>
this html has angularjs "code" ($scope.content
is loaded with something like this):
<script type='text/javascript' src='giveus.js'></script>
<div class="giveus-wrapper" ng-controller="GiveUsController">{{variable1}}</div>
Note that this snippet has ng-controller
. GiveUsController is lazy loaded at the same time that the embedded html (not in head). There is no error declaring this controller because It has been already tested.
My controller is as easy as:
angular.module("tf").controller('GiveUsController', function ($scope, $http)
{
console.debug("GiveUsController loaded");
$scope.variable1 = "hi!";
}
there is no console debug nor variable1
assignment
It looks like there is no controller binding to that <div>
.
I don't know how I can inject html with angular controller and make it work...
Any idea?
Upvotes: 3
Views: 2328
Reputation: 16979
You could do what you are wanting with a bit of manual html compilation. Here is an approach that is essentially a directive wrapper for the $compile service. Observe the following example and usage...
<div class="category-wrapper" ng-html="content"></div>
.controller('ctrl', function($scope) {
$scope.content = '<div class="giveus-wrapper" ng-controller="GiveUsController">{{variable1}}</div>'
})
.controller('GiveUsController', function($scope) {
console.log('hello from GiveUsController')
$scope.variable1 = 'I am variable 1'
})
.directive('ngHtml', ['$compile', function ($compile) {
return function (scope, elem, attrs) {
if (attrs.ngHtml) {
elem.html(scope.$eval(attrs.ngHtml));
$compile(elem.contents())(scope);
}
scope.$watch(attrs.ngHtml, function (newValue, oldValue) {
if (newValue && newValue !== oldValue) {
elem.html(newValue);
$compile(elem.contents())(scope);
}
});
};
}]);
JSFiddle Link - demo
Upvotes: 4
Reputation: 384
Angular for itself don't bind the ng-directives that are added into the DOM.
The $sce.compile or $compile helps angular to read which elements are added into the actual DOM, also for use the $compile you must use a directive.
Should be like that:
var m = angular.module(...);
m.directive('directiveName', function factory(injectables) {
return = {
priority: 0,
template: '<div></div>', // or // function(tElement, tAttrs) { ... },
transclude: false,
restrict: 'A',
templateNamespace: 'html',
scope: false,
controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
controllerAs: 'stringIdentifier',
bindToController: false,
require: 'siblingDirectiveName', 'optionalDirectiveName', '?^optionalParent'],
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
post: function postLink(scope, iElement, iAttrs, controller) { ... }
}
},
};
});
and where you want
$compileProvider.directive('compile', function($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
}
);
};
Upvotes: 1
Reputation: 250
You have to compile the HTML content, i got this using a directive:
.directive('comunBindHtml', ['$compile', function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
}])
Hope it helps :)
Upvotes: 0