Home  >  Article  >  Web Front-end  >  Learn AngularJs: Directive instruction usage (full version)_AngularJS

Learn AngularJs: Directive instruction usage (full version)_AngularJS

WBOY
WBOYOriginal
2016-05-16 15:03:481980browse

This tutorial uses AngularJs version: 1.5.3

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

AngularJs download address: https://angularjs.org/

Summary: Directive (instruction) I think is one of the very powerful and useful functions of AngularJ. It is equivalent to writing public custom DOM elements or CLASS attributes or ATTR attributes for us, and it is not just that, you can also operate scope, bind events, change styles, etc. based on it. Through this Directive, we can encapsulate many public instructions, such as paging instructions, auto-completion instructions, etc. Then you only need to simply write a line of code in the HTML page to achieve many powerful functions. Generally speaking, Directive needs to be used in the following situations:
1. Make your Html more semantic, and you can know the general logic of the page without delving into the code and logic.
2. Abstract a custom component and reuse it elsewhere.

1. The definition of Directive and how to use it
The directive definition of AngularJs is roughly as follows

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

Directive can be placed in element names, attributes, classes, and comments. The following is the equivalent way of referencing the myDir directive. (But many directives are limited to the use of "attributes")

<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> 

The following is an example:

<!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> 

Result:


The following is a detailed version of the 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; 
 
}); 

2. Interpretation of Directive content
You can see that it has 8 contents
1.restrict
(String) optional parameter, indicating in what form the instruction is declared in the DOM; the values ​​are: E (element), A (attribute), C (class), M (comment), where the default value is A; of course You can also use two together, such as EA. It can be an element or an attribute.
[html] view plain copy View code snippets on CODE derived to my code snippets
E (element): 3d2e5ffc584136bb402056fc25c74042fd34349817ec1e88fe5ef4ceedb13309
A (attribute):6eac651395124439dad6853c8943e57316b28748ea4df4d9c2150843fecfba68
C (class): c9319480cb6dde66254d6e5a18255f6c16b28748ea4df4d9c2150843fecfba68
M (comment): 1e6309f9690257b4da2f913028604ecf
Generally, E/A/C is used more.
2.priority
(number), optional parameter, indicating the priority of the instruction. If there are multiple instructions on a single DOM, the one with higher priority will be executed first;

3.terminal
(Boolean), optional parameter, can be set to true or false. If set to true, other instructions with a lower priority than this instruction will be invalid and will not be called (those with the same priority It will still be executed)

4.template (string or function) optional parameter, which can be:
(1) A piece of HTML text

<!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) A function that accepts two parameters tElement and tAttrs
Among them, tElement refers to the element using this instruction, and tAttrs is the attribute of the instance. It is a collection (object) composed of all attributes on the element, such as:
b610f1cd76609e8fc4e8d1105fb66e8a1e1283272b9f904b0d566db0f51327df
Where title is the attribute on tattrs

Let’s take a look at what happens when template is a 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> 
<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> 

Result:


You can see that the title field in the tag in hello-world2 is also used in the instruction

5.templateUrl (string or function), optional parameter, can be
(1) A string representing the HTML file path

(2) A function that accepts two parameters tElement and tAttrs (roughly the same as above)

Note: When developing locally, you need to run a server, otherwise using templateUrl will report a Cross Origin Request Script (CORS) error. Since HTML templates are loaded asynchronously, loading a large number of templates will slow down the website. Here is a trick, which is to cache the templates first
You can include the following code as part of your page after your index page is loaded.

<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:"dc6dce4a544fdca2df29d5ac0ea9906bhello every 144e86f8e6a2df8d24469044d39968c016b28748ea4df4d9c2150843fecfba6816b28748ea4df4d9c2150843fecfba68",这时,指令内部的内容会嵌入到ng-transclude这个div中。也就是变成了dc6dce4a544fdca2df29d5ac0ea9906bhello every dc6dce4a544fdca2df29d5ac0ea9906b这是指令内部的内容16b28748ea4df4d9c2150843fecfba6816b28748ea4df4d9c2150843fecfba68。默认值为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 command, 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 instruction 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 - 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: ディレクティブ命令の使用法の全内容です。皆様の学習に役立つことを願っています。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn