在web开发中我们经常需要将动态拼接的html字符串绑定到页面DOM上。
AngularJS中我们可以使用指令ng-bind-html
来绑定动态Html,它会将计算出来的表达式结果用innerHtml
绑定到html。
但是AngularJS默认是不相信添加的html内容的,所以我们需要调用$sce
(Strict Contextual Escaping)服务来解决问题。
$sce is included by default starting with angular 1.2
<!DOCTYPE html>
<html ng-app ="myApp">
<head>
<meta charset="utf-8">
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<style>
body{
border: 5px solid #FF851B;
padding: 10px;
}
.info{
color:#0074D9;
}
.age{
color:#FF4136;
}
</style>
</head>
<body ng-controller="myCtrl">
<div ng-bind-html="html"></div>
<script>
angular.module('myApp', [])
.controller("myCtrl", ["$scope","$sce",function($scope,$sce) {
$scope.myage = 16;
$scope.myInfo = {
name:"chenjy"
};
var html ="<div>my name:<span class='info'>chenjy</span>,my age:<span class='age'>16</span></div>";
$scope.html = $sce.trustAsHtml(html);
}]);
</script>
</body>
</html>
对于静态html这就够了,但是我们如果需要用到AngularJS强大的双向数据绑定能力
var html ="<div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div>";
ng-bind-html
并不会和$scope
双向绑定,并且ng-click
等指令也不会得到compile
- 我们可以借助
$compile
编译html
<body ng-controller="myCtrl">
<script>
angular.module('myApp', [])
.controller("myCtrl", ["$scope","$compile",function($scope,$compile) {
$scope.myage = 16;
$scope.myInfo = {
name:"chenjy"
};
var template ="<div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div>";
var ele = $compile(template)($scope);
angular.element(document.body).append(ele);
}]);
</script>
</body>
但是AngularJS中我们最好直接写在directive
的link
中,此时编译阶段已经结束我们可以手动编译html。
.directive("myDir", ["$compile",function($compile) {
return {
restrict: "E",
link: function(scope, iElement, iAttrs) {
var template = "<div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div><input type='text' ng-model='myage' />";
var ele = $compile(template)(scope);
iElement.append(ele);
}
};
}]);
下面贴一个网上看到的比较通用的compile
例子
<!DOCTYPE html>
<html ng-app ="myApp">
<head>
<meta charset="utf-8">
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<style>
body{
border: 5px solid #FF851B;
padding: 10px;
}
.info{
color:#0074D9;
}
.age{
color:#FF4136;
}
</style>
</head>
<body ng-controller="myCtrl">
<html-compile html='{{html}}'></html-compile>
<script>
angular.module('myApp', [])
.controller("myCtrl", ["$scope","$sce",function($scope,$sce) {
$scope.myage = 16;
$scope.myInfo = {
name:"chenjy"
};
$scope.changeAge = function(){
$scope.myage ++;
};
$scope.html ="<button ng-click='changeAge()'>change</button><div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div>";
}]).directive("htmlCompile", ["$compile", function($compile) {
return {
replace: true,
restrict: 'EA',
link: function(scope, elm, iAttrs) {
var DUMMY_SCOPE = {
$destroy: angular.noop
},
root = elm,
childScope,
destroyChildScope = function() {
(childScope || DUMMY_SCOPE).$destroy();
};
// 监听html值
iAttrs.$observe("html", function(html) {
/**
* 当传入html的时候 先尝试销毁子scope,然后创建一个子scope,compile当前html,替换掉当前DOM
**/
if (html) {
destroyChildScope();
childScope = scope.$new(false);
var content = $compile(html)(childScope);
root.replaceWith(content);
root = content;
}
// 在父scope销毁的时候,销毁该子scope
scope.$on("$destroy", destroyChildScope);
});
}
};
}]);
</script>
</body>
</html>