Compiling dynamic HTML strings from database
ng-bind-html-unsafe
only renders the content as HTML. It doesn't bind Angular scope to the resulted DOM. You have to use $compile
service for that purpose. I created this plunker to demonstrate how to use $compile
to create a directive rendering dynamic HTML entered by users and binding to the controller's scope. The source is posted below.
demo.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<script src="script.js"></script>
</head>
<body>
<h1>Compile dynamic HTML</h1>
<div ng-controller="MyController">
<textarea ng-model="html"></textarea>
<div dynamic="html"></div>
</div>
</body>
</html>
script.js
var app = angular.module('app', []);
app.directive('dynamic', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.dynamic, function(html) {
ele.html(html);
$compile(ele.contents())(scope);
});
}
};
});
function MyController($scope) {
$scope.click = function(arg) {
alert('Clicked ' + arg);
}
$scope.html = '<a ng-click="click(1)" href="#">Click me</a>';
}
Compile dynamic HTML and bind variable from JSON response - Directive with Isolated scope - AngularJS
When you receive the JSON data you can use angular.fromJSON
to decode the json string into the array (unless you are using the $http.get() which already does that for you)...
//request the JSON from server
jsonString = SomeFactory.fetchDataFromServer();
$scope.dataArray = angular.fromJson(jsonString);
...and then use the ngRepeat
to create multiple elements:
<div ng-repeat="element in dataArray" dynamic="element"></div>
Modify your directive like this:
app.directive('dynamic', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.bindData = {};
scope.$watch(attrs.dynamic, function(dynamic) {
console.log('Watch called');
ele.html(dynamic.htmlTemplate); //here's your htmlTemplate being compiled
$compile(ele.contents())(scope);
scope.bindData = dynamic.bindData; //here's your bound data ifyou need the reference
scope.name = dynamic.bindData.name; //bound data property name
}, true); //deep watch
}
};
});
Edit: Or you could simply pass element.htmlTemplate
and element.bindData
separately to the directive through two separate attributes as mentioned in an answer by user Vineet, which makes more sense.
Edit2: Fixed some bugs.
Here's the fiddle: Fiddle
Angularjs dynamic html string compilation with an directive included inside
I have figured out the problem!! Assiging scope.ctrl with ctrl resolves the issue of not updating modalctrl.form
Plunker with working solution: http://plnkr.co/edit/ovz2RJDmnHPgLUqUaH7M
model.directive('dynamicInput', ['$compile', '$sce',
function($compile, $sce) {
return {
templateUrl: 'myContent.html',
require: '^ngController',
restrict: 'EA',
link: function(scope, element, attrs, ctrl) {
scope.ctrl = ctrl;
var html = '<content-input name=' + attrs.name + '></content-input>';
scope.html = $sce.trustAsHtml(html);
}
};
}
]);
dynamic html in angular js
In angular you have to tell the application that the HTML can be trusted.
https://docs.angularjs.org/api/ng/service/$sce
In the HTML you should set a html variable like:
<div ng-bind-html="htmlFromDB"></div>
in the controller you would use $sce
$scope.htmlFromDB = $sce.trustAsHtml(//somehtml)
This can be super dangerous, and add vulnerabilities to Cross site scripting. So make sure you know where that HTML came from!
Related Topics
How to Get the Client Ip Address from Browser in Angular (Typescript)
Two Submit Buttons in One Form
Position: Sticky Buttons Not Working in Ie 11
How to Remove the Space Between Inline/Inline-Block Elements
Why Don't Flex Items Shrink Past Content Size
How to Vertically Align Elements in a Div
Chrome Ignores Autocomplete="Off"
Center and Bottom-Align Flex Items
Which HTML Elements Can Receive Focus
Fixed Page Header Overlaps In-Page Anchors
How to Center Text (Horizontally and Vertically) Inside a Div Block
How to Hide a Text and Make It Accessible by Screen Reader
Mystery White Space Underneath Image Tag
Css Negation Pseudo-Class :Not() For Parent/Ancestor Elements
Can't Scroll to Top of Flex Item That Is Overflowing Container