亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

理解AngularJs指令

2024-05-06 16:26:02
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了AngularJs指令
 

對于指令,可以把它簡單的理解成在特定DOM元素上運行的函數,指令可以擴展這個元素的功能。

首先來看個完整的參數示例再來詳細的介紹各個參數的作用及用法:

angular.module('myApp', []) .directive('myDirective', function() {   return {     restrict: String,     priority: Number,     terminal: Boolean,     template: String or Template Function:   function(tElement, tAttrs) {...},   templateUrl: String,   replace: Boolean or String,   scope: Boolean or Object,   transclude: Boolean,   controller: String or   function(scope, element, attrs, transclude, otherInjectables) { ... },   controllerAs: String,   require: String,   link: function(scope, iElement, iAttrs) { ... },   compile: // 返回一個對象或連接函數,如下所示:  function(tElement, tAttrs, transclude) {     return {       pre: function(scope, iElement, iAttrs, controller) { ... },       post: function(scope, iElement, iAttrs, controller) { ... }       }     return function postLink(...) { ... }     }   };  });

1、restrict[string]

restrict是一個可選的參數。用于指定該指令在DOM中以何種形式被聲明。默認值是A,即以屬性的形式來進行聲明。
可選值如下:
E(元素)

<my-directive></my-directive> 
A(屬性,默認值)

<div my-directive="expression"></div> 
C(類名)

<div class="my-directive:expression;"></div> 
M(注釋)

<--directive:my-directive expression-->
一般考慮到瀏覽器的兼容性,強烈建議使用默認的屬性就可以即即以屬性的形式來進行聲明。最后一種方式建議再不要求逼格指數的時候千萬不要用。

Code:

 angular.module('app',[])  .directive('myDirective', function () {      return {         restrict: 'E',         template: '<a href="http://www.baidu.com">百度</a>'       };    })HtmlCode: <my-directive></my-directive>

 效果:理解AngularJs指令

2、priority[int]

大多數指令會忽略這個參數,使用默認值0,但也有些場景設置高優先級是非常重要甚至是必須的。例如,ngRepeat將這個參數設置為1000,這樣就可以保證在同一元素上,它總是在其他指令之前被調用。

3、terminal[bool]

這個參數用來停止運行當前元素上比本指令優先級低的指令。但同當前指令優先級相同的指令還是會被執行。
例如:ngIf的優先級略高于ngView(它們操控的實際就是terminal參數),如果ngIf的表達式值為true,ngView就可以被正常執行,但如果ngIf表達式的值為false,由于ngView的優先級較低就不會被執行。

4、template[string or function]

template參數是可選的,必須被設置為以下兩種形式之一:

  • 一段HTML文本;
  • 一個可以接受兩個參數的函數,參數為tElement和tAttrs,并返回一個代表模板的字符串。tElement和tAttrs中的t代表template,是相對于instance的。

首先演示下第二種用法:

angular.module('app',[])  .directive('myDirective', function () {      return {         restrict: 'EAC',         template: function (elem, attr) {          return "<a href='" + attr.value + "'>" + attr.text + "</a>";        }    };  })

HtmlCode:(效果同上,不做演示了)

<my-directive value="http://www.baidu.com" text="百度"></my-directive>    <div my-directive       value="http://www.baidu.com"       text="百度"></div>

5、templateUrl[string or function]

templateUrl是可選的參數,可以是以下類型:

  • 一個代表外部HTML文件路徑的字符串;
  • 一個可以接受兩個參數的函數,參數為tElement和tAttrs,并返回一個外部HTML文件路徑的字符串。

無論哪種方式,模板的URL都將通過ng內置的安全層,特別是$getTrustedResourceUrl,這樣可以保護模板不會被不信任的源加載。 默認情況下,調用指令時會在后臺通過Ajax來請求HTML模板文件。加載大量的模板將嚴重拖慢一個客戶端應用的速度。為了避免延遲,可以在部署應用之前對HTML模板進行緩存。

Code:

 angular.module('app',[])  .directive('myDirective', function () {      return {         restrict: 'AEC',         templateUrl: function (elem, attr) {          return attr.value + ".html"; //當然這里我們可以直接指定路徑,同時在模板中可以包含表達式        }    };  })

6、replace[bool]

replace是一個可選參數,如果設置了這個參數,值必須為true,因為默認值為false。默認值意味著模板會被當作子元素插入到調用此指令的元素內部,
例如上面的示例默認值情況下,生成的html代碼如下:

<my-directive value="http://www.baidu.com" text="百度"><a href="http://www.baidu.com">百度</a></my-directive>

如果設置replace=true

<a href="http://www.baidu.com" value="http://www.baidu.com" text="百度">百度</a>

據我觀察,這種效果只有設置restrict="E"的情況下,才會表現出實際效果。

介紹完基本的指令參數后,就要涉及到更重要的作用域參數了...

7、scope參數[bool or object]

 scope參數是可選的,可以被設置為true或一個對象。默認值是false。

如果一個元素上有多個指令使用了隔離作用域,其中只有一個可以生效。只有指令模板中的根元素可以獲得一個新的作用域。因此,對于這些對象來說scope默認被設置為true。內置指令ng-controller的作用,就是從父級作用域繼承并創建一個新的子作用域。它會創建一個新的從父作用域繼承而來的子作用域。這里的繼承就不在贅述,和面向對象中的繼承基本是一直的。

 首先我們來分析一段代碼:

 <div ng-app="app" ng-init="name= '祖父'">      <div ng-init="name='父親'">        第一代:{{ name }}        <div ng-init="name= '兒子'" ng-controller="SomeController">          第二代: {{ name }}          <div ng-init="name='孫子'">            第三代: {{ name }}          </div>        </div>      </div>    </div> 

我們發現第一代,我們初始化name為父親,但是第二代和第三代其實是一個作用域,那么他們的name其實是一個對象,因此出現的效果如下:

第一代:父親
第二代: 孫子
第三代: 孫子

我們在修改一下代碼,把第三代隔離開來再看看效果:

 

<div ng-app="app"ng-init="name= '祖父'">      <div ng-init="name='父親'">        第一代:{{ name }}        <div ng-init="name= '兒子'" ng-controller="SomeController">          第二代: {{ name }}          <div ng-init="name='孫子'" ng-controller="SecondController">            第三代: {{ name }}          </div>        </div>      </div>    </div>

JsCode:

 angular.module('app', [])    .controller('SomeController',function($scope) {          })    .controller('SecondController', function ($scope) {      }) 

效果如下:

第一代:父親
第二代: 兒子
第三代: 孫子

在修改下代碼來看看繼承:

    <div ng-app="app"ng-init="name= '祖父的吻'">      <div>        第一代:{{ name }}        <div ng-controller="SomeController">          第二代: {{ name }}          <div ng-controller="SecondController">            第三代: {{ name }}          </div>        </div>      </div>    </div> 

效果如下:

第一代:祖父的吻
第二代: 祖父的吻
第三代: 祖父的吻

如果要創建一個能夠從外部原型繼承作用域的指令,將scope屬性設置為true,簡單來說就是可繼承的隔離,即不能反向影響父作用域。

 再來看個例子:

  angular.module('myApp', [])    .controller('MainController', function ($scope) {    })    .directive('myDirective', function () {      return {        restrict: 'A',        scope:false,//切換為{},true測試        priority: 100,        template: '<div>內部:{{ myProperty }}<input ng-model="myProperty"/></div>'      };    });

Html代碼:

 <div ng-controller='MainController' ng-init="myProperty='Hello World!'">    外部: {{ myProperty}}    <input ng-model="myProperty" />    <div my-directive></div>  </div>

當我們改變scope的值我們會發現

false:繼承但不隔離

理解AngularJs指令

true:繼承并隔離

理解AngularJs指令

{}:隔離且不繼承

理解AngularJs指令

 8、transclude

transclude是一個可選的參數。默認值是false。嵌入通常用來創建可復用的組件,典型的例子是模態對話框或導航欄。我們可以將整個模板,包括其中的指令通過嵌入全部傳入一個指令中。指令的內部可以訪問外部指令的作用域,并且模板也可以訪問外部的作用域對象。為了將作用域傳遞進去,scope參數的值必須通過{}或true設置成隔離作用域。如果沒有設置scope參數,那么指令內部的作用域將被設置為傳入模板的作用域。

只有當你希望創建一個可以包含任意內容的指令時,才使用transclude: true。

 我們來看兩個例子-導航欄:

<div side-box    <div class="tagcloud">      <a href="">Graphics</a>      <a href="">ng</a>      <a href="">D3</a>      <a href="">Front-end</a>      <a href="">Startup</a>    </div>  </div>

JsCode:

 angular.module('myApp', [])  .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>'      };   }); 

這段代碼告訴ng編譯器,將它從DOM元素中獲取的內容放到它發現ng-transclude指令的地方。

再來你看個官網的例子:

angular.module('docsIsoFnBindExample', []) .controller('Controller', ['$scope', '$timeout', function($scope, $timeout) {  $scope.name = 'Tobias';  $scope.hideDialog = function () {   $scope.dialogIsHidden = true;   $timeout(function () {    $scope.dialogIsHidden = false;   }, 2000);  }; }]) .directive('myDialog', function() {  return {   restrict: 'E',   transclude: true,   scope: {    'close': '&onClose'   },   templateUrl: 'my-dialog-close.html'  }; });

my-dialog-close.html

<div class="alert"> <a href class="close" ng-click="close()">×</a> <div ng-transclude></div></div>

index.html

<div ng-controller="Controller"> <my-dialog ng-hide="dialogIsHidden" on-close="hideDialog()">  Check out the contents, {{name}}! </my-dialog></div>

如果指令使用了transclude參數,那么在控制器無法正常監聽數據模型的變化了。建議在鏈接函數里使用$watch服務。

 9、controller[string or function]

 controller參數可以是一個字符串或一個函數。當設置為字符串時,會以字符串的值為名字,來查找注冊在應用中的控制器的構造函數.

angular.module('myApp', []) .directive('myDirective', function() { restrict: 'A', controller: 'SomeController' }) 

可以在指令內部通過匿名構造函數的方式來定義一個內聯的控制器

angular.module('myApp',[]) .directive('myDirective', function() { restrict: 'A', controller: function($scope, $element, $attrs, $transclude) { // 控制器邏輯放在這里} }); 

我們可以將任意可以被注入的ng服務注入到控制器中,便可以在指令中使用它了??刂破髦幸灿幸恍┨厥獾姆湛梢员蛔⑷氲街噶町斨?。這些服務有:

1. $scope

與指令元素相關聯的當前作用域。
2. $element
當前指令對應的元素。
3. $attrs
由當前元素的屬性組成的對象。

<div id="aDiv"class="box"></div>具有如下的屬性對象:{ id: "aDiv", class: "box" } 

4. $transclude
嵌入鏈接函數會與對應的嵌入作用域進行預綁定。transclude鏈接函數是實際被執行用來克隆元素和操作DOM的函數。

 angular.module('myApp',[]) .directive('myLink', function () {   return {     restrict: 'EA',     transclude: true,     controller:     function ($scope, $element,$attrs,$transclude) {       $transclude(function (clone) {                var a = angular.element('<a>');         a.attr('href', $attrs.value);         a.text(clone.text());         $element.append(a);       });     }   }; });

html 

<my-link value="http://www.baidu.com">百度</my-link><div my-link value="http://www.google.com">谷歌</div>

僅在compile參數中使用transcludeFn是推薦的做法。link函數可以將指令互相隔離開來,而controller則定義可復用的行為。如果我們希望將當前指令的API暴露給其他指令使用,可以使用controller參數,否則可以使用link來構造當前指令元素的功能性(即內部功能)。如果我們使用了scope.$watch()或者想要與DOM元素做實時的交互,使用鏈接會是更好的選擇。使用了嵌入,控制器中的作用域所反映的作用域可能與我們所期望的不一樣,這種情況下,$scope對象無法保證可以被正常更新。當想要同當前屏幕上的作用域交互時,可以使用傳入到link函數中的scope參數。

10、controllerAs[string]

controllerAs參數用來設置控制器的別名,這樣就可以在視圖中引用控制器甚至無需注入$scope。

<div ng-controller="MainController as main">    <input type="text" ng-model="main.name" />    <span>{{ main.name }}</span>  </div> 

JsCode:

 angular.module('myApp',[])  .controller('MainController', function () {    this.name = "Halower";  });

控制器的別名使路由和指令具有創建匿名控制器的強大能力。這種能力可以將動態的對象創建成為控制器,并且這個對象是隔離的、易于測試。

11、 require[string or string[]]

 require為字符串代表另外一個指令的名字。require會將控制器注入到其所指定的指令中,并作為當前指令的鏈接函數的第四個參數。字符串或數組元素的值是會在當前指令的作用域中使用的指令名稱。在任何情況下,ng編譯器在查找子控制器時都會參考當前指令的模板。

如果不使用^前綴,指令只會在自身的元素上查找控制器。指令定義只會查找定義在指令作當前用域中的ng-model=""
如果使用?前綴,在當前指令中沒有找到所需要的控制器,會將null作為傳給link函數的第四個參數。
如果添加了^前綴,指令會在上游的指令鏈中查找require參數所指定的控制器。
 如果添加了?^ 將前面兩個選項的行為組合起來,我們可選擇地加載需要的指令并在父指令鏈中進行查找
如果沒有任何前綴,指令將會在自身所提供的控制器中進行查找,如果沒有找到任何控制器(或具有指定名字的指令)就拋出一個錯誤
12、compile【object or function】

compile選項本身并不會被頻繁使用,但是link函數則會被經常使用。本質上,當我們設置了link選項,實際上是創建了一個postLink() 鏈接函數,以便compile() 函數可以定義鏈接函數。通常情況下,如果設置了compile函數,說明我們希望在指令和實時數據被放到DOM中之前進行DOM操作,在這個函數中進行諸如添加和刪除節點等DOM操作是安全的。

compile和link選項是互斥的。如果同時設置了這兩個選項,那么會把compile所返回的函數當作鏈接函數,而link選項本身則會被忽略。

編譯函數負責對模板DOM進行轉換。鏈接函數負責將作用域和DOM進行鏈接。 在作用域同DOM鏈接之前可以手動操作DOM。在實踐中,編寫自定義指令時這種操作是非常罕見的,但有幾個內置指令提供了這樣的功能。

13、link

compile: function(tEle, tAttrs, transcludeFn) { //todo: return function(scope, ele, attrs) { // 鏈接函數 };

鏈接函數是可選的。如果定義了編譯函數,它會返回鏈接函數,因此當兩個函數都定義時,編譯函數會重載鏈接函數。如果我們的指令很簡單,并且不需要額外的設置,可以從工廠函數(回調函數)返回一個函數來代替對象。如果這樣做了,這個函數就是鏈接函數。

14、ngModel

它提供更底層的API來處理控制器內的數據,這個API用來處理數據綁定、驗證、 CSS更新等不實際操作DOM的事情,ngModel 控制器會隨 ngModel 被一直注入到指令中,其中包含了一些方法。為了訪問ngModelController必須使用require設置.

ngModelController常用的元素如下:

 1).為了設置作用域中的視圖值,需要調用 ngModel.$setViewValue() 函數。
$setViewValue() 方法適合于在自定義指令中監聽自定義事件(比如使用具有回調函數的jQuery插件),我們會希望在回調時設置$viewValue并執行digest循環。

 angular.module('myApp')    .directive('myDirective', function() {      return {        require: '?ngModel',        link: function(scope, ele, attrs, ngModel) {          if (!ngModel) return;          $(function() {            ele.datepicker({               //回調函數              onSelect: function(date) {                // 設置視圖和調用 apply                scope.$apply(function() {                  ngModel.$setViewValue(date);                });              }            });          });        }      };    });

2).$render方法可以定義視圖具體的渲染方式
3).屬性(這里屬性可以參考前一篇文章末尾進行學習)

以上就是關于AngularJs指令的全部內容,希望對大家的學習有所幫助。



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久免费精品视频| 欧美性videos高清精品| 亚洲精品av在线| 亚洲专区中文字幕| 精品自在线视频| 午夜精品久久久久久久久久久久久| 日韩激情第一页| 久久久久久久久综合| 欧美裸体xxxx极品少妇| 亚洲欧洲免费视频| 91国产美女在线观看| 久久综合88中文色鬼| 国产日韩专区在线| 欧美日韩在线视频观看| 亚洲午夜色婷婷在线| 国产精品久久久久免费a∨大胸| 亚洲国内高清视频| 欧美极品少妇全裸体| 91亚洲精品久久久久久久久久久久| 96pao国产成视频永久免费| 在线视频精品一| 国产精品大陆在线观看| 日韩中文理论片| 日韩激情av在线播放| 97视频在线观看免费高清完整版在线观看| 播播国产欧美激情| 2019亚洲男人天堂| 欧美性猛交xxxxx水多| 国产精品入口夜色视频大尺度| 国产精品女人久久久久久| 亚洲人午夜精品| 欧美大片免费观看在线观看网站推荐| 国产欧美一区二区三区四区| 亚洲精品成人av| 精品欧美激情精品一区| 国产日韩欧美在线看| 日本a级片电影一区二区| 欧美美女18p| 久久久伊人欧美| 91精品久久久久久久久| 欧亚精品在线观看| 亚洲日韩第一页| 北条麻妃一区二区在线观看| 成人免费网站在线| 91亚洲精品视频| 亚洲精品视频在线播放| 欧洲成人在线视频| 久久精品人人做人人爽| 91精品一区二区| 国产美女直播视频一区| 中文字幕日韩av综合精品| 九色成人免费视频| 欧美老女人在线视频| 黄网站色欧美视频| 亚洲天堂久久av| 精品久久久久久国产91| 亚洲高清色综合| 日韩av在线网址| 亚洲欧洲国产精品| 久久亚洲精品毛片| 日韩av男人的天堂| 精品成人av一区| 91亚洲人电影| 久久国产精品电影| 精品一区二区亚洲| 国产欧美亚洲视频| 日韩免费中文字幕| 55夜色66夜色国产精品视频| 亚洲欧美激情另类校园| 日韩女在线观看| 色综合五月天导航| 色哟哟亚洲精品一区二区| 国产欧美 在线欧美| 51午夜精品视频| 亚洲精品日产aⅴ| 亚洲护士老师的毛茸茸最新章节| 日韩av最新在线观看| 久久久久久久久久久国产| 亚洲精品欧美日韩专区| 久久亚洲欧美日韩精品专区| 国产一区二区三区中文| 最新91在线视频| 亚洲深夜福利视频| 亚洲爱爱爱爱爱| 亚洲爱爱爱爱爱| 爱福利视频一区| 国产成人涩涩涩视频在线观看| 午夜精品一区二区三区在线视频| 久久亚洲国产精品成人av秋霞| 国内精品美女av在线播放| 欧美性色视频在线| 国产精品视频一区二区三区四| 国产精品视频内| 欧美电影在线观看网站| 成人性生交xxxxx网站| 精品久久久久久久久久久| 亚洲综合中文字幕在线观看| 久久久久久伊人| 亚洲色图25p| 精品呦交小u女在线| 精品一区二区三区四区在线| 亚洲欧洲中文天堂| 国产欧美va欧美va香蕉在| 九九精品视频在线观看| 亚洲精品久久久久中文字幕二区| 欧美国产在线电影| 久久久久久久久久久网站| 欧美人在线观看| 日韩av一区二区在线观看| 77777亚洲午夜久久多人| 精品久久香蕉国产线看观看亚洲| 国产啪精品视频| 日韩精品视频在线观看网址| 影音先锋欧美精品| 亚洲精品自在久久| 久久影院在线观看| 欧美精品video| 久热精品视频在线免费观看| 亚洲天堂网站在线观看视频| 欧美不卡视频一区发布| 国产一区二区三区三区在线观看| 91精品视频一区| 91久久国产精品| 欧美国产精品va在线观看| 日韩在线观看免费av| 欧美日韩国产综合新一区| 色偷偷偷综合中文字幕;dd| 日韩欧美在线国产| 国产日韩精品一区二区| 在线观看日韩www视频免费| 在线播放日韩专区| 日本久久久久久| 欧美又大粗又爽又黄大片视频| 亚洲色图第三页| 欧美激情中文字幕乱码免费| 精品亚洲一区二区三区四区五区| 亚洲社区在线观看| 欧美一乱一性一交一视频| 成人妇女淫片aaaa视频| 91精品免费久久久久久久久| 日本午夜在线亚洲.国产| 国产精品男女猛烈高潮激情| 欧美一级淫片aaaaaaa视频| 日韩成人在线播放| 伊人一区二区三区久久精品| 久久免费在线观看| 精品国产网站地址| 亚洲香蕉成人av网站在线观看| 欧美与黑人午夜性猛交久久久| 91国自产精品中文字幕亚洲| 久久久久久久久久久久av| 91免费人成网站在线观看18| 91亚洲精品一区二区| 亚洲男人的天堂在线播放| 精品一区二区电影| 韩国精品久久久999| 久久精彩免费视频| 中文字幕日韩av综合精品| 久久精品国产91精品亚洲| 亚洲精品黄网在线观看| 国产精品夜色7777狼人| 中文字幕精品av| 亚洲欧美综合精品久久成人| 在线观看视频亚洲|