在AngularJS中,操作DOM一般在指令中完成,事件监听机制是在对于已经静态生成的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听。
举例来说:
angular.module('myapp',[]) .directive('myText',function(){ return{ restrict:'A', template:'<div ng-click="hello()">Hi everyone</div>', link:function(scope,ele,attr){ } } })
这个指令中,会生成新的DOM节点:
<div ng-click="hello()">Hi everyone</div>
但是如果不做处理,这里的ng-click事件并不能实现,因为事件的监听在静态html页面生成时候已经完成。那么如何给动态生成的元素,绑定事件,实现事件的动态监听呢?
通过$compile服务,编译DOM,实现动态的事件绑定
var template:'<div ng-click="hello()">Hi everyone</div>', var content = $compile(template)(scope);
通过这两句,首先先编译DOM,然后用编译后的DOM加入到之前的静态节点中,就能实现动态绑定事件,之类注意,应该注入$compile service
.directive('myText',function($compile){})
完整的代码如下:
angular.module('myapp',[]) .directive('myText',function($compile){ var template:'<div ng-click="hello()">Hi everyone</div>', return{ restrict:'A', link:function(scope,ele,attr){ ele.on("click", function() { scope.$apply(function() { var content = $compile(template)(scope); element.append(content); }) }); } } })
另外一个例子:
var myApp = angular.module('myApp', []); myApp.controller('MainCtrl', ['$scope','$compile',function($scope, $compile) { $scope.count = 0; $scope.add = function() { if(event.target.tagName.toLowerCase()=="input")return; var target=$(event.target); $scope.count++; target.html($compile("<input value='"+$scope.count+"' ng-blur='showValue()'>")($scope)); } $scope.showValue=function(){ alert(event.target.value) } }])
注 : 这里用到了$compile服务,官方的解释是compile可以将一个HTML字符串或者DOM编译成模板,该模板能够与scope链接起来,也就是说 直接插入一段html片段到页面中,虽然能插入进去,但是angular并没有编译,所以任何ng事件指令绑定都是无效的,通过compile能够将 html片段先编译后再插入。
至此,<AngularJS动态生成的元素绑定事件>目的达到!