首頁 > web前端 > js教程 > 學習AngularJs:Directive指令用法(完整版)_AngularJS

學習AngularJs:Directive指令用法(完整版)_AngularJS

WBOY
發布: 2016-05-16 15:03:48
原創
1991 人瀏覽過

本教學使用AngularJs版本:1.5.3

AngularJs GitHub: https://github.com/angular/angular.js/

AngularJs下載網址:https://angularjs.org/

摘要:Directive(指令)筆者認為是AngularJ非常強大且有有用的功能之一。它就相當於為我們寫了公共的自訂DOM元素或CLASS屬性或ATTR屬性,而且它不只是單單如此,你還可以在它的基礎上來操作scope、綁定事件、更改樣式等。透過這個Directive,我們可以封裝很多公共指令,像是分頁指令、自動補全指令等等。然後在HTML頁面裡只需要簡單的寫一行程式碼就可以實現很多強大的功能。一般情況下,需要用Directive有下面的情景:
1. 讓你的Html更具語意化,不需要深入研究程式碼和邏輯即可知道頁面的大致邏輯。
2. 抽象化一個自訂元件,在其他地方進行重複使用。

一、Directive的定義及其使用方法
AngularJs的指令定義大致如下

angular.module("app",[]).directive("directiveName",function(){ 
 return{ 
 //通过设置项来定义 
 }; 
}) 
登入後複製

Directive可以放置於元素名稱、屬性、class、註解中。以下是引用myDir這個directive的等價方式。 (但很多directive都限制為「屬性」的使用方式)

<span <span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span><span style="font-family: Arial, Helvetica, sans-serif;">="exp"></span>//属性</span> 
 
<span class="<span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span>: exp;"></span>//class 
 
<<span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span>></<span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span>>//元素 
 
<!-- directive: <span style="font-family: Arial, Helvetica, sans-serif;">directive-name </span><span style="font-family: Arial, Helvetica, sans-serif;">exp -->//注释</span> 
登入後複製

如下一個實例 :

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<hello-world></hello-world> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.directive('helloWorld', function() { 
 return { 
 restrict: 'E', 
 template: '<div>Hi 我是林炳文~~~</div>', 
 replace: true 
 }; 
}); 
</script> 
</html> 
登入後複製

結果:


下面是一個directive的詳細版

var myModule = angular.module(...); 
 
myModule.directive('directiveName', function factory(injectables) { 
 
 var directiveDefinitionObject = { 
 
   priority: 0, 
 
   template: '<div></div>', 
 
   templateUrl: 'directive.html', 
 
   replace: false, 
 
   transclude: false, 
 
   restrict: 'A', 
 
   scope: false, 
 
   compile: function compile(tElement, tAttrs, transclude) { 
 
     return { 
 
       pre: function preLink(scope, iElement, iAttrs, controller) { ... }, 
 
       post: function postLink(scope, iElement, iAttrs, controller) { ... } 
 
    } 
 
  }, 
 
   link: function postLink(scope, iElement, iAttrs) { ... } 
 
}; 
 
 return directiveDefinitionObject; 
 
}); 
登入後複製

二、Directive指令內容解讀
可 以看到它有8個內容
1.restrict
(字串)可選參數,指明指令在DOM裡面以什麼形式被宣告;取值有:E(元素),A(屬性),C(類),M(註解),其中預設值為A;當然也可以兩個一起用,例如EA.表示即可以是元素也可以是屬性。
[html] view plain copy 在CODE上查看代碼片派生到我的代碼片
E(元素): 
A(屬性):

 
C(類別):
 
M(註):<--directive:directiveName expression--> 
一般情況下E/A/C用得比較多。
2.priority
(數字),可選參數,指明指令的優先級,若在單一DOM上有多個指令,則優先級高的先執行;

3.terminal
(布林型),可選參數,可以設定為true或false,若設為true,則優先權低於此指令的其他指令則無效,不會被呼叫(優先權相同的還是會執行)

4.template(字串或函數)可選參數,可以是:
(1)一段HTML文字

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<hello-world></hello-world> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.directive('helloWorld', function() { 
 return { 
 restrict: 'E', 
 template: '<div><h1>Hi 我是林炳文~~~</h1></div>', 
 replace: true 
 }; 
}); 
</script> 
</html> 
登入後複製

(2)一個函數,可接受兩個參數tElement和tAttrs
其中tElement是指使用此指令的元素,而tAttrs則實例的屬性,它是一個由元素上所有的屬性組成的集合(物件)形如:
 
其中title就是tattrs上的屬性

下面讓我們來看看template是一個函數時候的情況

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<hello-world></hello-world> 
<hello-world2 title = '我是第二个directive'></hello-world2> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.directive('helloWorld', function() { 
 return { 
 restrict: 'E', 
 template: '<div><h1>Hi 我是林炳文~~~</h1></div>', 
 replace: true 
 }; 
}); 
app.directive("helloWorld2",function(){ 
 return{ 
 restrict:'EAC', 
 template: function(tElement,tAttrs){ 
 var _html = ''; 
 _html += '<div>' +'hello '+tAttrs.title+'</div>'; 
 return _html; 
 } 
 }; 
 }); 
</script> 
</html> 
登入後複製

結果:


可以看到指令中也用到了hello-world2中的標籤中的 title欄位

5.templateUrl(字串或函數),可選參數,可以是
(1)一個代表HTML檔案路徑的字串

(2)一個函數,可接受兩個參數tElement和tAttrs(大致同上)

注意:在本機開發時候,需要執行一個伺服器,不然使用templateUrl會報錯 Cross Origin Request Script(CORS)錯誤。由於載入html模板是透過非同步載入的,若載入大量的模板會拖慢網站的速度,這裡有個技巧,就是先快取模板
你可以再你的index頁面載入好的,將下列程式碼作為你頁面的一部分包含在裡面。

<script type='text/ng-template' id='hello.html'> 
 <div><h1>Hi 我是林炳文~~~</h1></div> 
</script> 
登入後複製

这里的id属性就是被设置在templateUrl上用的。

 
 
 
  
 AngularJS入门学习 
  

<script type='text/ng-template' id='hello.html'> <div><h1>Hi 我是林炳文~~~</h1></div> </script>
登入後複製

输出结果:


另一种办法缓存是:

app.run(["$templateCache", function($templateCache) { 
 $templateCache.put("hello.html", 
 "<div><h1>Hi 我是林炳文~~~</h1></div>"); 
}]); 
登入後複製

使用实例如下:

 
 
 
  
 AngularJS入门学习 
  

登入後複製

结果:


其实第一种方法还好一些,写起来会比较快,笔者就得最多的也是第一种写法,直接包在scprit当中

6.replace
(布尔值),默认值为false,设置为true时候,我们再来看看下面的例子(对比下在template时候举的例子)

replace为true时,hello-world这个标签不在了,反之,则存在。

7.scope
(1)默认值false。表示继承父作用域;

(2)true。表示继承父作用域,并创建自己的作用域(子作用域);

(3){}。表示创建一个全新的隔离作用域;

7.1首先我们先来了解下scope的继承机制。我们用ng-controller这个指令举例,

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<div ng-controller='MainController'> 
 父亲:{{name}}<input ng-model="name" /> 
 <div my-directive></div> 
 </div> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.controller('MainController', function ($scope) { 
 $scope.name = '林炳文'; 
}); 
app.directive('myDirective', function () { 
 return { 
 restrict: 'EA', 
 scope:false, 
 template: '<div>儿子:{{ name }}<input ng-model="name"/></div>' 
 }; 
}); 
</script> 
</html> 
登入後複製

接下来我们通过一个简单明了的例子来说明scope取值不同的差别:

scope:false

scope:true

scope:{}

当为false时候,儿子继承父亲的值,改变父亲的值,儿子的值也随之变化,反之亦如此。(继承不隔离)

当为true时候,儿子继承父亲的值,改变父亲的值,儿子的值随之变化,但是改变儿子的值,父亲的值不变。(继承隔离)

当为{}时候,没有继承父亲的值,所以儿子的值为空,改变任何一方的值均不能影响另一方的值。(不继承隔离)

tip:当你想要创建一个可重用的组件时隔离作用域是一个很好的选择,通过隔离作用域我们确保指令是‘独立'的,并可以轻松地插入到任何HTML app中,并且这种做法防止了父作用域被污染;
7.2隔离作用域可以通过绑定策略来访问父作用域的属性。
directive 在使用隔离 scope 的时候,提供了三种方法同隔离之外的地方交互。这三种分别是

@ 绑定一个局部 scope 属性到当前 dom 节点的属性值。结果总是一个字符串,因为 dom 属性是字符串。
& 提供一种方式执行一个表达式在父 scope 的上下文中。如果没有指定 attr 名称,则属性名称为相同的本地名称。
= 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。

@ 局部 scope 属性

@ 方式局部属性用来访问 directive 外部环境定义的字符串值,主要是通过 directive 所在的标签属性绑定外部字符串值。这种绑定是单向的,即父 scope 的绑定变化,directive 中的 scope 的属性会同步变化,而隔离 scope 中的绑定变化,父 scope 是不知道的。

如下示例:directive 声明未隔离 scope 类型,并且使用@绑定 name 属性,在 directive 中使用 name 属性绑定父 scope 中的属性。当改变父 scope 中属性的值的时候,directive 会同步更新值,当改变 directive 的 scope 的属性值时,父 scope 无法同步更新值。

js 代码:

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<div ng-controller="myController"> 
 <div class="result"> 
 <div>父scope: 
 <div>Say:{{name}}<br>改变父scope的name:<input type="text" value="" ng-model="name"/></div> 
 </div> 
 <div>隔离scope: 
 <div isolated-directive name="{{name}}"></div> 
 </div> 
 <div>隔离scope(不使用父scope {{name}}): 
 <div isolated-directive name="name"></div> 
 </div> 
 </div> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
 app.controller("myController", function ($scope) { 
 $scope.name = "hello world"; 
 }).directive("isolatedDirective", function () { 
 return { 
 scope: { 
 name: "@" 
 }, 
 template: 'Say:{{name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">' 
 }; 
}); 
</script> 
</html> 
登入後複製

结果:页面初始效果

动画效果:


可以看到父scope上的内容发生改变,子scope同时发生改变。而子scope上的内容发生改变。不影响父scope上的内容!

= 局部 scope 属性

= 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。
意思是,当你想要一个双向绑定的属性的时候,你可以使用=来引入外部属性。无论是改变父 scope 还是隔离 scope 里的属性,父 scope 和隔离 scope 都会同时更新属性值,因为它们是双向绑定的关系。

示例代码:

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<div ng-controller="myController"> 
 <div>父scope: 
 <div>Say:{{user.name}}<br>改变父scope的name:<input type="text" value="" ng-model="userBase.name"/></div> 
 </div> 
 <div>隔离scope: 
 <div isolated-directive user="userBase"></div> 
 </div> 
</div> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
 app.controller("myController", function ($scope) { 
 $scope.userBase = { 
 name: 'hello', 
 id: 1 
 }; 
 }).directive("isolatedDirective", function () { 
 return { 
 scope: { 
 user: "=" 
 }, 
 template: 'Say:{{user.name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="user.name"/>' 
 } 
 }) 
</script> 
</html> 
登入後複製

效果:

可以看到父scope和子scope上的内容一直都是一样的!
& 局部 scope 属性

& 方式提供一种途经是 directive 能在父 scope 的上下文中执行一个表达式。此表达式可以是一个 function。
比如当你写了一个 directive,当用户点击按钮时,directive 想要通知 controller,controller 无法知道 directive 中发生了什么,也许你可以通过使用 angular 中的 event 广播来做到,但是必须要在 controller 中增加一个事件监听方法。
最好的方法就是让 directive 可以通过一个父 scope 中的 function,当 directive 中有什么动作需要更新到父 scope 中的时候,可以在父 scope 上下文中执行一段代码或者一个函数。

如下示例在 directive 中执行父 scope 的 function。

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
 <div ng-controller="myController"> 
 <div>父scope: 
 <div>Say:{{value}}</div> 
 </div> 
 <div>隔离scope: 
 <div isolated-directive action="click()"></div> 
 </div> 
</div> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
 app.controller("myController", function ($scope) { 
 $scope.value = "hello world"; 
 $scope.click = function () { 
 $scope.value = Math.random(); 
 }; 
 }).directive("isolatedDirective", function () { 
 return { 
 scope: { 
 action: "&" 
 }, 
 template: '<input type="button" value="在directive中执行父scope定义的方法" ng-click="action()"/>' 
 } 
 }) 
</script> 
</html> 
登入後複製

效果:


指令的内容比较多,下面再来讲讲transclude、compline、link、contrller

8.transclude
如果不想让指令内部的内容被模板替换,可以设置这个值为true。一般情况下需要和ngTransclude指令一起使用。 比如:template:"

hello every
",这时,指令内部的内容会嵌入到ng-transclude这个div中。也就是变成了
hello every
这是指令内部的内容
。默认值为false;这个配置选项可以让我们提取包含在指令那个元素里面的内容,再将它放置在指令模板的特定位置。当你开启transclude后,你就可以使用ng-transclude来指明了应该在什么地方放置transcluded内容

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<div sidebox title="Links"> 
  <ul> 
  <li>First link</li> 
  <li>Second link</li> 
  </ul> 
</div> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.directive('sidebox', function() { 
 return { 
 restrict: 'EA', 
 scope: { 
  title: '@' 
 }, 
 transclude: true, 
 template: '<div class="sidebox">\ 
  <div class="content">\ 
  <h2 class="header">{{ title }}</h2>\ 
  <span class="content" ng-transclude>\ 
  </span>\ 
  </div>\ 
 </div>' 
 }; 
}); 
</script> 
</html> 
登入後複製

结果:

当 transclude: false,时

如果指令使用了transclude参数,那么在控制器无法正常监听数据模型的变化了。建议在链接函数里使用$watch服务。
9.controller
可以是一个字符串或者函数。

若是为字符串,则将字符串当做是控制器的名字,来查找注册在应用中的控制器的构造函数

angular.module('myApp', []) 
.directive('myDirective', function() { 
restrict: 'A', // 始终需要 
controller: 'SomeController' 
}) 
// 应用中其他的地方,可以是同一个文件或被index.html包含的另一个文件 
angular.module('myApp') 
.controller('SomeController', function($scope, $element, $attrs, $transclude) { 
// 控制器逻辑放在这里 
}); 
也可以直接在指令内部的定义为匿名函数,同样我们可以再这里注入任何服务($log,$timeout等等)

[html] view plain copy 在CODE上查看代码片派生到我的代码片
angular.module('myApp',[]) 
.directive('myDirective', function() { 
restrict: 'A', 
controller: 
function($scope, $element, $attrs, $transclude) { 
// 控制器逻辑放在这里 
} 
}); 

登入後複製

另外还有一些特殊的服务(参数)可以注入

(1)$scope,与指令元素相关联的作用域

(2)$element,当前指令对应的 元素

(3)$attrs,由当前元素的属性组成的对象

(4)$transclude,嵌入链接函数,实际被执行用来克隆元素和操作DOM的函数

注意: 除非是用来定义一些可复用的行为,一般不推荐在这使用。
指令的控制器和link函数(后面会讲)可以进行互换。区别在于,控制器主要是用来提供可在指令间复用的行为但link链接函数只能在当前内部指令中定义行为,且无法再指令间复用。

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入门学习</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
 <hello mycolor ="red">我是林炳文~~~</hello> 
</body> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.directive('hello', function() { 
 return { 
  restrict: 'EA', 
  transclude: true, //注意此处必须设置为true 
  controller: 
  function ($scope, $element,$attrs,$transclude,$log) { //在这里你可以注入你想注入的服务 
  $transclude(function (clone) { 
   var a = angular.element('<p>'); 
   a.css('color', $attrs.mycolor); 
   a.text(clone.text()); 
   $element.append(a); 
  }); 
  $log.info("hello everyone"); 
  } 
 }; 
 }); 
</script> 
</html> 
登入後複製

输出结果:


并且在控制台下输出hello everyone

让我们看看$transclude();在这里,它可以接收两个参数,第一个是$scope,作用域,第二个是带有参数clone的回调函数。而这个clone实际上就是嵌入的内容(经过jquery包装),可以在它上做很多DOM操作。

它还有最简单的用法就是

<script> 
 angular.module('myApp',[]).directive('mySite', function () { 
 return { 
  restrict: 'EA', 
  transclude: true, 
  controller: 
  function ($scope, $element,$attrs,$transclude,$log) { 
  var a = $transclude(); //$transclude()就是嵌入的内容 
  $element.append(a); 
  } 
 }; 
 }); 
 </script> 
登入後複製

注意:使用$transclude会生成一个新的作用域。
默认情况下,如果我们简单实用$transclude(),那么默认的其作用域就是$transclude生成的作用域

但是如果我们实用$transclude($scope,function(clone){}),那么作用域就是directive的作用域了

那么问题又来了。如果我们想实用父作用域呢

可以使用$scope.$parent

同理想要一个新的作用域也可以使用$scope.$parent.new();
10.controllerAs
这个选项的作用是可以设置你的控制器的别名

一般以前我们经常用这样方式来写代码:

angular.module("app",[]) 
 .controller("demoController",["$scope",function($scope){ 
 $scope.title = "angualr"; 
 }]) 
 
 <div ng-app="app" ng-controller="demoController"> 
 {{title}} 
</div> 
登入後複製

后来angularjs1.2给我们带来新语法糖,所以我们可以这样写

angular.module("app",[]) 
 .controller("demoController",[function(){ 
 this.title = "angualr"; 
 }]) 
 
 <div ng-app="app" ng-controller="demoController as demo"> 
 {{demo.title}} 
 </div> 
登入後複製

同样的我们也可以再指令里面也这样写

<script> 
 angular.module('myApp',[]).directive('mySite', function () { 
 return { 
  restrict: 'EA', 
  transclude: true, 
  controller:'someController', 
  controllerAs:'mainController' 
  //..其他配置 
 }; 
 }); 
 </script> 
登入後複製

11.require(字符串或者数组)
字符串代表另一个指令的名字,它将会作为link函数的第四个参数。具体用法我们可以举个例子说明。假设现在我们要编写两个指令,两个指令中的link链接函数中(link函数后面会讲)存在有很多重合的方法,这时候我们就可以将这些重复的方法写在第三个指令的controller中(上面也讲到controller经常用来提供指令间的复用行为)然后在这两个指令中,require这个拥有controller字段的的指令(第三个指令),

最后通过link链接函数的第四个参数就可以引用这些重合的方法了。

<!doctype html> 
<html ng-app="myApp"> 
<head> 
 <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script> 
</head> 
<body> 
 
  
 <outer-directive> 
 <inner-directive></inner-directive> 
 <inner-directive2></inner-directive2> 
 </outer-directive> 
 <script> 
 var app = angular.module('myApp', []); 
 app.directive('outerDirective', function() { 
  return { 
  scope: {}, 
  restrict: 'AE', 
  controller: function($scope) { 
   this.say = function(someDirective) { 
   console.log('Got:' + someDirective.message); 
   }; 
  } 
  }; 
 }); 
 app.directive('innerDirective', function() { 
  return { 
  scope: {}, 
  restrict: 'AE', 
  require: '^outerDirective', 
  link: function(scope, elem, attrs, controllerInstance) { 
   scope.message = "Hi,leifeng"; 
   controllerInstance.say(scope); 
  } 
  }; 
 }); 
 app.directive('innerDirective2', function() { 
  return { 
  scope: {}, 
  restrict: 'AE', 
  require: '^outerDirective', 
  link: function(scope, elem, attrs, controllerInstance) { 
   scope.message = "Hi,shushu"; 
   controllerInstance.say(scope); 
  } 
  }; 
 }); 
 
 
 </script> 
 
</body> 
</html> 
登入後複製

The instructions innerDirective and innerDirective2 in the above example reuse the method defined in the controller of the instruction outerDirective

also further explains that the controller in the instruction is used to communicate between different instructions.

In addition, we can add one of the following prefixes to the require parameter value, which will change the behavior of the search controller:

(1) Without prefix, the instruction will search in the controller provided by itself. If no controller is found, an error will be thrown

(2)? If the required controller is not found in the current instruction, null will be passed to the fourth parameter of the link connection function

(3)^If the required controller is not found in the current directive, the controller of the parent element will be searched

(4)?^ Combination

12.Anguar instruction compilation process
First load the angularjs library and find the ng-app directive to find the boundaries of the application,

Call the $compile service for compilation according to the scope defined by ng-app. Angularjs will traverse the entire HTML document and process each instruction declared on the page according to the definition of the instruction in js according to the priority of the instruction. ) arrangement, convert the DOM according to the configuration parameters (template, place, transclude, etc.) in the instruction and then start to execute the compile function of each instruction in order (if the compile function is defined on the instruction) to convert the template itself

Note: The compile function here is configured in our instructions, which is different from the $compile service mentioned above. After each compile function is executed, it will return a link function, and all link functions will be synthesized into one large link function

Then this big link function will be executed, mainly for data binding, by registering a listener on the DOM to dynamically modify the data in the scope, or using $watchs to listen to the variables in the scope to modify the DOM, thus Create two-way bindings and more. If the compile function is not configured in our instructions, the link function we configured will run. What she does is roughly the same as the large link function synthesized by all the link functions after compile returns above.

So: the compile and link options in the command are mutually exclusive. If these two options are set at the same time, the function returned by compile will be regarded as the link function, and the link option itself will be ignored

13. Compile function Compile function

function compile(tElement, tAttrs, transclude) { ... }
The compiled function is used to handle situations where the template DOM needs to be modified. Because most instructions do not require modifying the template, this function is not commonly used. Examples that need to be used include ngTrepeat, which requires modifying the template, and ngView, which requires asynchronous loading of content. The compiled function accepts the following parameters.

tElement - template element - The element where the directive is located. It is safe to perform operations such as transformations on this element and its children.
tAttrs - template attributes - attributes declared by all directives on this element. These attributes are shared among the compiled functions.
transclude - an embedded linking function function(scope, cloneLinkingFn).
Note: Do not perform any operations other than DOM transformation in the compiled function. More importantly, the registration of DOM listening events should be done in the link function, not the compiled function.
Compiled functions can return an object or function.
Returns a function - equivalent to the link function registered using the link attribute of the configuration object when the compiled function does not exist.
Return Object - Returns an object with a function registered via the pre or post attribute. See the explanation of pre-linking and post-liking functions below.

14. Linking function

function link(scope, iElement, iAttrs, controller) { ... }
The link function is responsible for registering DOM events and updating the DOM. It is executed after the template is cloned and is where most of the directive logic is written.
scope - the scope the directive needs to listen to.
iElement - instance element - The element where the instruction is located. It is only safe to operate on an element's children in the postLink function, because then they are all linked.
iAttrs - instance attributes - Instance attributes, a standardized list of all attributes declared on the current element. These attributes are shared among all link functions.
controller - the controller instance, which is the controller inside direct2 that the current instruction requests through require. For example: controller:function(){this.addStrength = function(){}} in the direct2 instruction, then in the link function of the current instruction, you can call it through controller.addStrength.
Pre-linking function is executed before child elements are linked. It cannot be used to transform the DOM in case the link function cannot find the correct element to link.
Post-linking function is executed after all elements are linked.

Instructions:

コンパイルオプション自体はあまり使用しませんが、リンク機能は頻繁に使用します。基本的に、リンク オプションを設定すると、実際に postLink() リンク関数が作成され、compile() 関数がリンク関数を定義できるようになります。通常、コンパイル関数が設定されている場合は、命令やリアルタイム データが DOM に配置される前に DOM 操作を実行する必要があることを意味します。この関数でノードの追加や削除などの DOM 操作を実行しても安全です。コンパイル オプションとリンク オプションは相互に排他的です。両方のオプションが設定されている場合、コンパイルによって返される関数はリンク関数として扱われ、リンク オプション自体は無視されます。変換関数は、テンプレート DOM の変換を担当します。 link 関数は、スコープを DOM にリンクする役割を果たします。 スコープが DOM にリンクされる前に、DOM を手動で操作できます。実際には、カスタム ディレクティブを作成するときにこの種の操作が行われることは非常にまれですが、そのような機能を提供する組み込みディレクティブがいくつかあります。 リンク機能はオプションです。コンパイル関数が定義されている場合、リンク関数が返されるため、両方の関数が定義されている場合、コンパイル関数はリンク関数をオーバーロードします。ディレクティブが単純で追加の設定が必要ない場合は、オブジェクトの代わりにファクトリ関数 (コールバック関数) から関数を返すことができます。これを行うと、その関数はリンク関数になります。

この記事から転載http://blog.csdn.net/evankaka

上記は AngularJs: ディレクティブ命令の使用法の全内容です。皆様の学習に役立つことを願っています。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板