AngularJS中的$compile服务
出处:http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx
创建一个AngularJSP的指令很容易,譬如下面这个例子
1 {{ message }} 2 <div otc-dynamic></div>
otcDynamic指令提供了一串HTML模板
1 app.directive("otcDynamic",function(){ 2 3 return{ 4 5 template:"<button 6 ng-click='doSomething()'>{{label}}</div>" 7 8 }; 9 10 });
结合控制器的定义,当用户点击按钮时,便会在页面上看到内容的变化
1 app.controller("mainController", function($scope){ 2 3 $scope.label = "Please click"; 4 $scope.doSomething = function(){ 5 $scope.message = "Clicked!"; 6 }; 7 8 });
动态化
假设otcDynamic指令不能使用静态模板。指令需要依赖上下文环境,譬如标记位、用户数据、服务信息等。下面来模拟这个场景,我们还是使用静态字符串,不过假设字符串是动态创建的,并且使用element.html函数插入到DOM元素中。
1 app.directive("otcDynamic", function(){ 2 return { 3 link: function(scope, element){ 4 element.html("<button ng-click='doSomething()'>{{label}}</button>"); 5 } 6 }; 7 });
上面的例子中,lablel内容不在会发生变化,即使用户点击按钮。最关键的原因时AngularJS已经过了编译阶段。
编译服务
借助AnglarJS的编译$compile服务,可以解决此问题
1 app.directive("otcDynamic", function($compile){ 2 return{ 3 link: function(scope, element){ 4 var template = "<button ng-click='doSomething()'>{{label}}</button>"; 5 var linkFn = $compile(template); 6 var content = linkFn(scope); 7 element.append(content); 8 } 9 } 10 });
如果要元素事件中或者非AngularJS的代码中使用$compile服务,需要配合$apply检测数据变化。
1 app.directive("otcDynamic", function($compile) { 2 3 var template = "<button ng-click='doSomething()'>{{label}}</button>"; 4 5 return{ 6 link: function(scope, element){ 7 element.on("click", function() { 8 scope.$apply(function() { 9 var content = $compile(template)(scope); 10 element.append(content); 11 }) 12 }); 13 } 14 } 15 });