Maison  >  Article  >  interface Web  >  Apprendre AngularJs : utilisation des instructions de directive (version complète)_AngularJS

Apprendre AngularJs : utilisation des instructions de directive (version complète)_AngularJS

WBOY
WBOYoriginal
2016-05-16 15:03:481980parcourir

Ce tutoriel utilise la version AngularJs : 1.5.3

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

Adresse de téléchargement d'AngularJs : https://angularjs.org/

Résumé : Directive (instruction) Je pense que c'est l'une des fonctions très puissantes et utiles d'AngularJ. Cela équivaut à écrire des éléments DOM personnalisés publics ou des attributs CLASS ou ATTR pour nous, et ce n'est pas seulement cela, vous pouvez également utiliser la portée, lier des événements, modifier les styles, etc. Grâce à cette directive, nous pouvons encapsuler de nombreuses instructions publiques, telles que les instructions de pagination, les instructions de saisie semi-automatique, etc. Il vous suffit ensuite d'écrire simplement une ligne de code dans la page HTML pour réaliser de nombreuses fonctions puissantes. De manière générale, Directive doit être utilisée dans les situations suivantes :
1. Rendez votre HTML plus sémantique et vous pourrez connaître la logique générale de la page sans vous plonger dans le code et la logique.
2. Extrayez un composant personnalisé et réutilisez-le ailleurs.

1. La définition de Directive et comment l'utiliser
La définition directive d'AngularJs est à peu près la suivante

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

La directive peut être placée dans les noms d'éléments, les attributs, les classes et les commentaires. Ce qui suit est la manière équivalente de référencer la directive myDir. (Mais de nombreuses directives se limitent à l'utilisation d'"attributs")

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

Ce qui suit est un exemple :

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

Résultat :


Ce qui suit est une version détaillée de la 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. Interprétation du contenu de la Directive
Vous pouvez voir qu'il a 8 contenus
1.restreindre
(String) paramètre facultatif, indiquant sous quelle forme l'instruction est déclarée dans le DOM ; les valeurs sont : E (élément), A (attribut), C (classe), M (commentaire), où la valeur par défaut est A. ; bien sûr, vous pouvez également en utiliser deux ensemble, comme EA. Il peut s'agir d'un élément ou d'un attribut.
[html] afficher la copie simple Afficher les extraits de code sur CODE dérivés de mes extraits de code
E (élément) : 3d2e5ffc584136bb402056fc25c74042fd34349817ec1e88fe5ef4ceedb13309 A (attribut) :6eac651395124439dad6853c8943e57316b28748ea4df4d9c2150843fecfba68 C (classe) : c9319480cb6dde66254d6e5a18255f6c16b28748ea4df4d9c2150843fecfba68 M (commentaire) : 1e6309f9690257b4da2f913028604ecf Généralement, E/A/C est davantage utilisé.


2.priorité

(numéro), paramètre facultatif, indiquant la priorité de l'instruction. S'il y a plusieurs instructions sur un même DOM, celle avec la priorité la plus élevée sera exécutée en premier
3.terminal

(Booléen), paramètre facultatif, peut être défini sur true ou false. S'il est défini sur true, les autres instructions avec une priorité inférieure à cette instruction seront invalides et ne seront pas appelées (celles avec la même priorité). sera toujours exécuté)
4.template (string ou fonction) paramètre facultatif, qui peut être :

(1) Un morceau de texte 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) Une fonction qui accepte deux paramètres tElement et tAttrs

Parmi eux, tElement fait référence à l'élément utilisant cette instruction, et tAttrs est l'attribut de l'instance. Il s'agit d'une collection (objet) composée de tous les attributs de l'élément, tels que : . e8a88c33be18ce43dcaf6622d4fcf9721e1283272b9f904b0d566db0f51327df Où le titre est l'attribut sur les tatouages

Regardons ce qui se passe lorsque le modèle est une fonction


Résultat :

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

Vous pouvez voir que le champ titre dans la balise dans hello-world2 est également utilisé dans l'instruction


5.templateUrl (string ou fonction), paramètre facultatif, peut être

(1) Une chaîne représentant le chemin du fichier HTML (2) Une fonction qui accepte deux paramètres tElement et tAttrs (à peu près les mêmes que ci-dessus)
Remarque : lors du développement local, vous devez exécuter un serveur, sinon l'utilisation de templateUrl signalera une erreur Cross Origin Request Script (CORS). Étant donné que les modèles HTML sont chargés de manière asynchrone, le chargement d'un grand nombre de modèles ralentira le site Web. Voici une astuce qui consiste à mettre d'abord les modèles en cache
. Vous pouvez inclure le code suivant dans votre page une fois votre page d'index chargée.

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

<!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', 
 templateUrl: 'hello.html', 
 replace: true 
 }; 
}); 
</script> 
<script type='text/ng-template' id='hello.html'> 
 <div><h1>Hi 我是林炳文~~~</h1></div> 
</script> 
</html> 

输出结果:


另一种办法缓存是:

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> 

Les instructions innerDirective et innerDirective2 dans l'exemple ci-dessus réutilisent la méthode définie dans le contrôleur de l'instruction externalDirective

explique également en outre que le contrôleur dans l'instruction est utilisé pour communiquer entre différentes instructions.

De plus, nous pouvons ajouter l'un des préfixes suivants à la valeur du paramètre require, ce qui modifiera le comportement du contrôleur de recherche :

(1) Sans préfixe, l'instruction recherchera dans le contrôleur fourni par elle-même. Si aucun contrôleur n'est trouvé, une erreur sera générée

.

(2) ? Si le contrôleur requis n'est pas trouvé dans l'instruction en cours, null sera passé au quatrième paramètre de la fonction de connexion de lien

(3)^Si le contrôleur requis n'est pas trouvé dans la directive actuelle, le contrôleur de l'élément parent sera recherché

(4) ?^ Combinaison

12.Processus de compilation des instructions Anguar
Chargez d'abord la bibliothèque angulairejs et recherchez la directive ng-app pour trouver les limites de l'application,

Appelez le service $compile pour la compilation selon la portée définie par ng-app parcourra l'intégralité du document HTML et traitera chaque instruction déclarée sur la page selon la définition de l'instruction en js selon la priorité de la. instruction. ), convertissez le DOM en fonction des paramètres de configuration (modèle, place, transclude, etc.) dans l'instruction puis commencez à exécuter la fonction de compilation de chaque instruction dans l'ordre (si la fonction de compilation est définie sur l'instruction). pour convertir le modèle lui-même

Remarque : la fonction de compilation ici est configurée dans nos instructions, ce qui est différent du service $compile mentionné ci-dessus. Une fois que chaque fonction de compilation est exécutée, elle renverra une fonction de lien et toutes les fonctions de lien seront synthétisées en une grande fonction de lien

Ensuite, cette grande fonction de lien sera exécutée, principalement pour la liaison de données, en enregistrant un écouteur sur le DOM pour modifier dynamiquement les données dans le scope, ou en utilisant $watchs pour écouter les variables dans le scope pour modifier le DOM, Créez ainsi des liaisons bidirectionnelles et plus encore. Si la fonction de compilation n'est pas configurée dans nos instructions, la fonction de lien que nous avons configurée s'exécutera. Ce qu'elle fait est à peu près la même que la grande fonction de lien synthétisée par toutes les fonctions de lien après les retours de compilation ci-dessus.

Donc : les options de compilation et de lien dans la commande s'excluent mutuellement. Si ces deux options sont définies en même temps, la fonction renvoyée par la compilation sera considérée comme la fonction de lien et l'option de lien elle-même sera ignorée

13. Fonction de compilation Fonction de compilation

fonction compile(tElement, tAttrs, transclude) { ... }
La fonction compilée est utilisée pour gérer les situations dans lesquelles le modèle DOM doit être modifié. Étant donné que la plupart des instructions ne nécessitent pas de modification du modèle, cette fonction n'est pas couramment utilisée. Les exemples qui doivent être utilisés incluent ngTrepeat, qui nécessite la modification du modèle, et ngView, qui nécessite un chargement asynchrone du contenu. La fonction compilée accepte les paramètres suivants.

tElement - élément de modèle - L'élément où se trouve la directive. Il est possible d'effectuer en toute sécurité des opérations telles que des transformations sur cet élément et ses enfants.
tAttrs - attributs du modèle - attributs déclarés par toutes les directives sur cet élément. Ces attributs sont partagés entre les fonctions compilées.
transclude - une fonction de fonction de liaison intégrée (scope, cloneLinkingFn).
Remarque : n'effectuez aucune opération autre que la transformation DOM dans la fonction compilée. Plus important encore, l'enregistrement des événements d'écoute DOM doit être effectué dans la fonction de lien, et non dans la fonction compilée.
Les fonctions compilées peuvent renvoyer un objet ou une fonction.
Renvoie une fonction - équivalente à la fonction de lien enregistrée à l'aide de l'attribut de lien de l'objet de configuration lorsque la fonction compilée n'existe pas.
Return Object - Renvoie un objet avec une fonction enregistrée via l'attribut pre ou post. Voir l'explication des fonctions de pré-lien et de post-aime ci-dessous.

14. Fonction de liaison

lien de fonction (portée, iElement, iAttrs, contrôleur) { ... }
La fonction de liaison est responsable de l'enregistrement des événements DOM et de la mise à jour du DOM. Il est exécuté après le clonage du modèle et c'est là que la majeure partie de la logique de directive est écrite.
scope - la portée que la directive doit écouter.
iElement - élément d'instance - L'élément où se trouve l'instruction. Il est uniquement sûr d'opérer sur les enfants d'un élément dans la fonction postLink, car ils sont alors tous liés.
iAttrs - attributs d'instance - Attributs d'instance, une liste standardisée de tous les attributs déclarés sur l'élément actuel. Ces attributs sont partagés entre toutes les fonctions de lien.
contrôleur - l'instance du contrôleur, qui est le contrôleur à l'intérieur de direct2 que l'instruction actuelle demande via require. Par exemple : controller:function(){this.addStrength = function(){}} dans l'instruction direct2, puis dans la fonction link de l'instruction en cours, vous pouvez l'appeler via controller.addStrength.
La fonction de pré-liaison est exécutée avant que les éléments enfants ne soient liés. Il ne peut pas être utilisé pour transformer le DOM au cas où la fonction de lien ne trouverait pas le bon élément à lier.
La fonction de post-liaison est exécutée une fois que tous les éléments sont liés.

Instructions :

L'option de compilation elle-même ne sera pas utilisée fréquemment, mais la fonction de lien sera fréquemment utilisée. Essentiellement, lorsque nous définissons l'option de lien, nous créons en fait une fonction de lien postLink() afin que la fonction compile() puisse définir la fonction de lien. Normalement, si la fonction de compilation est définie, cela signifie que nous voulons effectuer des opérations DOM avant que les instructions et les données en temps réel ne soient placées dans le DOM. Il est sûr d'effectuer des opérations DOM telles que l'ajout et la suppression de nœuds dans cette fonction. Les options de compilation et de liaison s'excluent mutuellement. Si les deux options sont définies, la fonction renvoyée par la compilation sera traitée comme la fonction de lien et l'option de lien elle-même sera ignorée. La fonction de traduction est responsable de la conversion du modèle DOM. La fonction de liaison est chargée de lier la portée au DOM. Vous pouvez manipuler manuellement le DOM avant que la portée ne soit liée au DOM. En pratique, ce type d'opération est très rare lors de l'écriture de directives personnalisées, mais il existe plusieurs directives intégrées qui fournissent une telle fonctionnalité. Les fonctions de lien sont facultatives. Si une fonction de compilation est définie, elle renvoie la fonction de lien, donc lorsque les deux fonctions sont définies, la fonction de compilation surcharge la fonction de lien. Si notre directive est simple et ne nécessite aucune configuration supplémentaire, nous pouvons renvoyer une fonction de la fonction d'usine (fonction de rappel) à la place de l'objet. Si vous faites cela, la fonction est une fonction de lien.

Réimprimé de cet articlehttp://blog.csdn.net/evankaka

Ce qui précède est l'intégralité du contenu de l'utilisation des instructions AngularJs:Directive. J'espère que cela sera utile à l'apprentissage de chacun.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn