angularjs 指令(directive)詳解(1)

原文地址


什麼是directive?我們先來看一下官方的解釋:

At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS'sHTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

Angular comes with a set of these directives built-in, like ngBindngModel, and ngClass. Much like you create controllers and services, you can create your own directives for Angular to use. When Angular bootstraps your application, the HTML compiler traverses the DOM matching directives against the DOM elements.

像ngBind,ngModel和ngClass等指令都是angular內置的directive,當我們感覺這些directive不能滿足我們的要求時,則可以自己動手創建directive。

我們定義的directive一般使用camelCase(駝峯)命名規則,但是由於HTML是不區分大小寫的,所以我們的directive在DOM中只能使用小寫,可以使用以下幾種方式來表示:

例如ngBind可以表示爲以下幾種方式:

  <span ng-bind="name"></span> <br/>
  <span ng:bind="name"></span> <br/>
  <span ng_bind="name"></span> <br/>
  <span data-ng-bind="name"></span> <br/>
  <span x-ng-bind="name"></span> <br/>

但我們一般常用下劃線來表示,如:ng-bing


瞭解完指令的定義,那麼接下來我們學習如何自己創建一個指令。

一.directive的寫法以及參數說明:

angular.module("app",[])
 .directive("directive",function(){
    return{
     	restrict:"EACM", //指明指令在DOM中以什麼樣的形式被聲明
		priority:0, //該指令的執行優先級
		terminal:true/false, //是否是最後一組執行的directive。
		template:"<div></div>", //模板
		template:"**/**.html", //指定模板的url
		replace:true/false,  //替換或拼接到當前元素
		transclude:true/false/'element', //將內容編譯後放入指定地方
		scope:true/false/{}, //創建一個新的作用域
		require:[],  //請求其他directive的controller
		controller:function/controllerName, //創建一個控制器,可與其他              .                                                    directive共享
		link:function, //操控DOM元素
		compile:function, //通過表示服修改DOM模板
    };
})

二.directive返回參數詳解


1.restrict

可選參數,指明指令在DOM裏面以什麼形式被聲明,默認爲A(屬性);

E(元素):<directive></directive>

A(屬性):<div directive='name'></div>

C(類):   <div class='directive'></div>

M(註釋):<–directive:directive name–>


2.priority

可選參數,指明指令的優先級,若在單個DOM上有多個指令,則優先級高的先執行,如果優先級相同,則執行順序是不確定的。


3.terminal

可選參數,可以被設置爲true或false,若設置爲true,則表示當前的priority將會成爲最後一組執行的directive。任何directive與當前的優先級相同的話,他們依然會執行,但順序是不確定。優先級低於此指令的其他指令則無效,不會被調用。


4.template

可選參數,html代碼,如下所示,

//js代碼
angular.module("app",[])
 .directive("hello",function(){
	return{
		restrict:'EA',
		template:"<div>templateUrl</div>"
	};
 })
//html代碼
<div>
	<hello></hello>
</div>

則輸出結果是:

templateUrl


5.templateUrl

可選參數,與template基本一致,但模版通過指定的url進行加載。因爲模版加載是異步的,所以compilation、linking都會暫停,等待加載完畢後再執行。

 

由於加載html模板是通過異步加載的,若加載大量的模板會拖慢網站的速度,可以先緩存模板來提高速度(可以使用ng-template或$templateCache來緩存模板,詳細用法在這裏不多說,請自行查詢)


6.replace

可選參數,默認爲false。如果設置爲true,那麼模版將會替換當前元素,否則作爲子元素添加到當前元素中。

當設爲true時:

//js代碼
angular.module("app",[])
 .directive("hello",function(){
	return{
		restrict:'EA',
		replace:true,
		template:"<div>templateUrl</div>"
	};
 })
//html代碼
<div>
	<hello></hello>
</div>

 

那麼渲染之後的代碼爲:

 <div>
	<div>templateUrl</div>
</div>

 

可以看到,<hello></hello>已經被<div>templateUrl</div>這個標籤替換掉了。

還是以上代碼,如果設爲false或不設值時,渲染之後的代碼爲:

<div>
	<hello>
		<div>templateUrl</div>
	</hello>
</div>

 

可以自己比較一下true和false的區別。


7.transclude

可選參數,默認值爲fasle。

指令的作用是把我們自定義的語義化標籤替換成瀏覽器能夠認識的HTML標籤。那麼,如果我們自定義的標籤內部出現了子標籤,應該如何去處理呢?

transclude可以讓我們提取包含在指令那個元素裏面的內容,再將它放置在指令模板的特定位置。我們可以使用ng-transclude來指明瞭應該在什麼地方放置transcluded內容。

看如下代碼:

 <!doctype html>
<html ng-app="myApp">
<head>
  <script src="angular.min.js"></script>
</head>
<body>

  <div ng-controller='controller'>
  	<hello>
       `text`
    </hello>
	<hello></hello>
  </div>

  <script>
    var app = angular.module('myApp',[]);
    app.controller('controller',function($scope){
      $scope.text = 'I am transclude';
    });
    app.directive('hello',function(){
     return {
        scope:{},  
        restrict: 'AE',
        transclude: true,
        template: '<div ng-transclude>hello world</div>'
     }
    });
  </script>
</body>
</html>

上邊代碼的輸出結果是:

I am transclude
hello world


當transclude設爲true的時候,會創建一個新的transclude空間,並且繼承了父作用域

我們再看看生成的html爲下圖所示,

可以發現第一個<hello>標籤裏的文本“hello world”消失了,這是因爲被transclude內容替換掉了。這裏的transclude內容就是`text`

我們將true換爲'element',如下圖所示:

轉換整個元素,包括其他優先級較低的directive。使用時,忽略其模板屬性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章