1、首先解释一下这个现象的原因,AngularJS是页面刷新时编译静态的html,只会编译一次;所以在后来在div中新增动态新增html的时候,这块新增的代码块是没有被编译的,所以里面和angular相关的绑定都失效了;
2、既然了解了是什么原因之后,才有了解决的头绪,就是说在动态增加代码块之后需要对这块代码进行编译,并且AngularJS中也提供了手动编译的功能(具体看代码);
3、编译的问题解决了,还需要考虑一个问题,那就是我不知道这块动态代码什么时候被添加,那么就需要监听这块代码,只要一有变化就执行一次编译,庆幸的是AngularJS同样提供了监听的功能;
分析完成后,现在看具体代码:
html:
<!DOCTYPE html>
<html lang="en" ng-app="angular-bind-html-compile">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="static/js/angular.js"></script>
</head>
<body ng-controller="myController">
<div bind-html-compile id="myDiv"></div><!--这个div里面的内容是动态加载的,需要手动编译-->
</body>
</html>
js:
<script>
var app = angular.module('angular-bind-html-compile', []);
/*注意:指令名bindHtmlCompile,要与监听的div一致
* */
app.directive('bindHtmlCompile', ['$compile',
function($compile) {
return {
restrict: 'EA',
link: function(scope, element) {
/*执行监听方法*/
scope.$watch(
function() {
return angular.element(document.querySelector("#myDiv")).html();/*监听dom元素,监听id为myDiv的html的变化*/
},
function(value) {/*div一有变化,就执行这个方法*/
element.html(value);
$compile(element.contents())(scope);/*手动编译这块代码*/
});
}
};
}]
);
app.controller("myController", function($scope, $interval){
$scope.test = "动态加载";
/*模拟动态生成,我写了一个定时添加功能,每隔5秒在myDiv中加一个代码块,并且该代码快中有angularjs属性,
如果生效则会显示成<a href='sss'>动态加载</a>*/
$interval(function () {
angular.element(document.querySelector("#myDiv")).append("<a href='sss'>{{test}}</a>");
}, 5000);
})
</script>
注意:
如果监听的是angualrjs的一个属性,那么directive中需要该一个地方:
link: function(scope, element, attrs) {
scope.$watch(function() {
return scope.$eval(attrs.bindHtmlCompile);//监听angular对象,bindHtmlCompile是监听属性的驼峰写法
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
});
}
最后说一个我实际遇到的问题,我是刚开始使用angualrjs,之前一直使用的jquery,动态加载模态框的时候是走了一下后台查询了相关数据返回到一个模板上,再load到模态框的body中去;同样也是动态加载的问题:具体解决看代码:
<!DOCTYPE html>
<html lang="en" ng-app="angular-bind-html-compile">
<head>
<meta charset="UTF-8">
<title></title>
<link href="static/css/bootstrap.css" rel="stylesheet">
<script type="text/javascript" src="static/js/jquery.js"></script>
<script src="static/js/bootstrap.min.js"></script>
<script type="text/javascript" src="static/js/angular.js"></script>
</head>
<body ng-controller="myController">
<button id="sample_editable_1_delete" class="btn red" style="margin-left: 10px;" ng-click="add()">
模态框 <i class="icon-minus"></i>
</button>
<div id="create_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel3" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h3 id="myModalLabel3">创建/修改用例</h3>
</div>
<div class="modal-body" bind-html-compile id="a">
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" ng-click="mis()" aria-hidden="true">关闭</button>
<button class="btn green btn-primary" οnclick="saveProductCase();">保存</button>
</div>
</div>
<script>
var module = angular.module('angular-bind-html-compile', []);
module.directive('bindHtmlCompile', ['$compile',
function($compile) {
return {
restrict: 'EA',
link: function(scope, element) {
scope.$watch(function() {
return $("#myDiv").html();/*监听dom*/
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
});
}
};
}]
);
module.controller("myController", function($scope, $interval, $http){
$scope.test = "wwwww";
$scope.add = function(){
$("#myDiv").empty();
$http.get("/test/modal").then(function(rep){
$scope.list = rep.data;
$("#myDiv").append(rep.data);
});
$("#create_modal").modal();
}
})
</script>
</html>
后台:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created by zelei.fan on 2017/5/19.
*/
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/modal")
public String modal(){
return "/test/testmodal";
}
}