摘要:引言指令可以說是的核心,而其開發(fā)也是比較困難的,本文主要介紹指令的一些參數(shù)和的綁定策略。指令執(zhí)行的優(yōu)先級,用于多個(gè)指令同時(shí)作用于同一個(gè)元素時(shí)。改變父會(huì)影響指令,而改變指令不會(huì)影響父。在父和指令之間建立雙向綁定。
引言
指令(Directive)可以說是 AngularJS 的核心,而其開發(fā)也是比較困難的,本文主要介紹指令的一些參數(shù)和scope的綁定策略。
參數(shù)從 AngularJS 的官方文檔中看到指令的參數(shù)如下:
{ priority: 0, template: "", // or // function(tElement, tAttrs) { ... }, // or // templateUrl: "directive.html", // or // function(tElement, tAttrs) { ... }, transclude: false, restrict: "A", scope: false, controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, controllerAs: "stringAlias", require: "siblingDirectiveName", // or // ["^parentDirectiveName", "?optionalDirectiveName", "?^optionalParent"], compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) { ... }, post: function postLink(scope, iElement, iAttrs, controller) { ... } } // or // return function postLink( ... ) { ... } }, // or // link: { // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, // post: function postLink(scope, iElement, iAttrs, controller) { ... } // } // or // link: function postLink( ... ) { ... } }
下面詳細(xì)講解每個(gè)參數(shù)。
priority(Number)指令執(zhí)行的優(yōu)先級,用于多個(gè)指令同時(shí)作用于同一個(gè)元素時(shí)。例如:
上面的例子中,ng-repeat 指令和 ng-bind 指令同時(shí)作用于 option 元素,由于 ng-repeat 的 priority 為1000,ng-bind 的 priority 為0,因此先執(zhí)行 ng-repeat,然后變量 i 的值才能用于 ng-bind 中。
template(String or Function)HTML模板內(nèi)容,用于下列情況之一:
替換元素的內(nèi)容(默認(rèn)情況)。
替換元素本身(如果 replace 選項(xiàng)為 true)。
將元素的內(nèi)容包裹起來(如果 transclude 選項(xiàng)為 true,后面會(huì)細(xì)說)。
值可以是:
一個(gè) HTML 字符串。例如:
一個(gè)函數(shù),接收兩個(gè)參數(shù) tElement(元素本身) 和 tAttrs(元素的屬性集合),返回 HTML 字符串。
templateUrl(String or Function)templateUrl 和 template 作用相同,但模板內(nèi)容是從 $templateCache 服務(wù)或遠(yuǎn)程 url 加載。
值可以是:
一個(gè)字符串,AngularJS 會(huì)先從 $templateCache 中查找是否緩存了對應(yīng)值,如果沒有則嘗試 ajax 加載。例如:在頁面中有如下 script:
AngularJS 會(huì)將 type="text/ng-template" 的 script 標(biāo)簽中的內(nèi)容以 id 值為 key 緩存到 $templateCache 服務(wù)中,此時(shí)可以設(shè)置 templateUrl: "Hello.html"。
一個(gè)函數(shù),接收兩個(gè)參數(shù) tElement(元素本身) 和 tAttrs(元素的屬性集合),返回 url 地址。
transclude(Boolean)官方文檔的解釋為:編譯元素的內(nèi)容,使其在指令內(nèi)部可用。該選項(xiàng)一般和 ng-transclude 指令一起使用。
如果 transclude 設(shè)置為 true,則元素的內(nèi)容會(huì)被放到模板中設(shè)置了 ng-transclude 指令的元素中。例如:
app.directive("testTransclude", [ function () { return { restrict: "E", transclude: true, template: "" }; } ]);指令內(nèi)部段落
該段落會(huì)被放到指令內(nèi)部
上面生成后的 DOM 結(jié)構(gòu)為:
restrict(String)指令的使用形式。
值可以為:
"E" - 指令作為元素使用
"A" - 指令作為屬性使用
"C" - 指令作為類名使用
"M" - 指令作為注釋使用(不常用)
可以是以上值的組合,如 restrict: "EA" 表示指令既可以作為屬性使用,也可以作為元素使用。
scope(Boolean or Object)關(guān)于 scope 選項(xiàng)將會(huì)在后面的指令 scope 中細(xì)說。
controller(Function)一般情況下不需要使用指令的 controller,只要使用 link 就夠了,后面會(huì)細(xì)說 link 函數(shù)。
用 controller 的場景是該指令(a)會(huì)被其他指令(b)require 的時(shí)候,在 b 的指令里可以傳入 a 的這個(gè) controller,目的是為了指令間的復(fù)用和交流。而 link 只能在指令內(nèi)部中定義行為,無法做到這樣。
controllerAs(String)為控制器指定別名,這樣可以在需要控制器的地方使用該名字進(jìn)行注入。
require(String or Array)表示指令依賴于一個(gè)或多個(gè)指令,并注入所依賴指令的控制器到 link 函數(shù)的第四個(gè)參數(shù)中。如果所依賴的指令不存在,或所依賴指令的控制器不存在則會(huì)報(bào)錯(cuò)。
依賴名稱前綴可以為:
(沒有前綴) - 在當(dāng)前元素中查找依賴指令的控制器,如果不存在則報(bào)錯(cuò)。
? - 在當(dāng)前元素中查找依賴指令的控制器,如果不存在傳 null 到 link 中。
^ - 在當(dāng)前元素及父元素中查找依賴指令的控制器,如果不存在則報(bào)錯(cuò)。
?^ - 在當(dāng)前元素及父元素中查找依賴指令的控制器,如果不存在傳 null 到 link 中。
例子:
app.directive("validate", [ function () { return { restrict: "A", require: "ngModel", link: function (scope, ele, attrs, ngModelCtrl) { // 監(jiān)聽值變化 ngModelCtrl.$viewChangeListeners.push(function () { scope.validateResult = ngModelCtrl.$viewValue === "Heron"; }); } }; } ]); app.controller("myCtrl", [ "$scope", "$cookieStore", function ($scope, $cookieStore) { $scope.name = "Heron"; $scope.sayHi = function (name, age) { alert("Hello " + name + ", your age is " + age); } } ]);
validate 結(jié)果:{{validateResult}}
運(yùn)行結(jié)果如圖:
compile(Function) 和 link(Function)創(chuàng)建的創(chuàng)建過程可以分為編譯(compile)階段和鏈接(link)階段,因此兩者放一起講。
兩者區(qū)別在于:
compile 函數(shù)的作用是對指令的模板進(jìn)行轉(zhuǎn)換。
link 函數(shù)的作用是在視圖和模型之間建立關(guān)聯(lián),包括注冊事件監(jiān)聽函數(shù)和更新 DOM 操作。
scope 在鏈接階段才會(huì)被綁定到元素上,因此 compile 函數(shù)中沒有入?yún)?scope。
對于同一個(gè)指令的多個(gè)示例,compile 函數(shù)只會(huì)執(zhí)行一次,而 link 函數(shù)在每個(gè)實(shí)例中都會(huì)執(zhí)行。
如果自定義了 compile 函數(shù),則自定義的 link 函數(shù) 無效,而是使用 compile 函數(shù) 返回的 link 函數(shù)。
指令 scopescope 選項(xiàng)有三種值:
false - 使用父 scope。改變父 scope 會(huì)影響指令 scope,反之亦然。
true - 繼承父 scope,并創(chuàng)建自己的 scope。改變父 scope 會(huì)影響指令 scope,而改變指令 scope 不會(huì)影響父 scope。
{} - 不繼承父 scope,創(chuàng)建獨(dú)立的 scope。如果不使用雙向綁定策略(后面會(huì)講),改變父 scope 不會(huì)影響指令 scope,反之亦然。
例子:
app.controller("myCtrl", [ "$scope", "$cookieStore", function ($scope, $cookieStore) { $scope.scopeFalse = "Heron"; $scope.scopeTrue = "Heron"; $scope.scopeObject = "Heron"; } ]); app.directive("directiveFalse", [ function () { return { restrict: "EA", scope: false, template: "" }; } ]); app.directive("directiveTrue", [ function () { return { restrict: "EA", scope: true, template: "指令 scope:
" }; } ]); app.directive("directiveObject", [ function () { return { restrict: "EA", scope: {}, template: "指令 scope:
", link: function (scope) { // 由于使用獨(dú)立scope,因此需要自己定義變量 scope.scopeObject = "Heron"; } }; } ]);指令 scope:
scope: false
父 scope:
scope: true
父 scope:
scope: {}
父 scope:
運(yùn)行結(jié)果如圖:
針對獨(dú)立 scope,可以通過在對象中聲明如何從外部傳入?yún)?shù)。有以下三種綁定策略:
@ - 使用 DOM 屬性值單項(xiàng)綁定到指令 scope 中。此時(shí)綁定的值總是一個(gè)字符串,因?yàn)?DOM 的屬性值是一個(gè)字符串。
scope: { age: "@" }
= - 在父 scope 和指令 scope 之間建立雙向綁定。
scope: { age: "=" }
& - 使用父 scope 的上下文執(zhí)行函數(shù)。一般用于綁定函數(shù)。
scope: { sayHi: "&" }
綁定函數(shù)時(shí),有時(shí)需要向指令外部傳遞參數(shù),如下:
app.controller("myCtrl", [ "$scope", "$cookieStore", function ($scope, $cookieStore) { $scope.name = "Heron"; $scope.sayHi = function (name, age) { alert("Hello " + name + ", your age is " + age); }; } ]); app.directive("myDirective", [ function () { return { restrict: "E", replace: true, scope: { clickMe: "&" }, template: "", link: function (scope) { scope.age = 26; } }; } ]);
運(yùn)行結(jié)果如圖:
說明一下:首先聲明 clickMe: "&" 使用父 scope 的環(huán)境執(zhí)行 clickMe 函數(shù),然后在傳遞給指令時(shí)聲明 click-me="sayHi(name, age)",表示父 scope 的 sayHi 方法需要兩個(gè)參數(shù),一個(gè)是 name,一個(gè)是 age,然后再指令中使用對象 {} 的方式向外傳遞參數(shù),如 ng-click="clickMe({ age: age })",表示向指令外傳遞 age 參數(shù),sayHi 方法從指令拿到 age 參數(shù),再從自己的上下文中拿到 name 參數(shù)。
結(jié)語AngularJS 指令的開發(fā)和使用千變?nèi)f化,也有許多坑,希望大家留意,也希望大家能在評論區(qū)多多交流心得。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88126.html
摘要:自定義指令中有很多內(nèi)置指令,一般都是以開頭的比如等等。本文介紹的自定義指令的用法。該參數(shù)的意思是替換指令的內(nèi)容,更改上面的例子。將屬性綁定到父控制器的域中學(xué)習(xí)概念多指令中的參數(shù)中增加了的值和的點(diǎn)擊函數(shù)。 自定義指令 angularjs中有很多內(nèi)置指令,一般都是以ng開頭的;比如:ng-app,ng-click,ng-repeat等等。本文介紹angularjs的自定義指令的用法。 指令...
摘要:自定義指令中有很多內(nèi)置指令,一般都是以開頭的比如等等。本文介紹的自定義指令的用法。該參數(shù)的意思是替換指令的內(nèi)容,更改上面的例子。將屬性綁定到父控制器的域中學(xué)習(xí)概念多指令中的參數(shù)中增加了的值和的點(diǎn)擊函數(shù)。 自定義指令 angularjs中有很多內(nèi)置指令,一般都是以ng開頭的;比如:ng-app,ng-click,ng-repeat等等。本文介紹angularjs的自定義指令的用法。 指令...
摘要:可選參數(shù),布爾值或者對象默認(rèn)值為,可能取值默認(rèn)值。布爾值或者字符,默認(rèn)值為這個(gè)配置選項(xiàng)可以讓我們提取包含在指令那個(gè)元素里面的內(nèi)容,再將它放置在指令模板的特定位置。 前言 最近學(xué)習(xí)了下angularjs指令的相關(guān)知識,也參考了前人的一些文章,在此總結(jié)下。 歡迎批評指出錯(cuò)誤的地方。 Angularjs指令定義的API showImg(https://segmentfault.com/img...
摘要:新增的日期選擇器。類型必填必填最小長度最大長度正則匹配正則匹配更新觸發(fā)即使沒有使用校驗(yàn)屬性,只要數(shù)據(jù)不符合格式,就會(huì)被更新成。 input[text] input一般和ngModel結(jié)合使用來實(shí)現(xiàn)雙向綁定,同時(shí)angular提供了很多表單校驗(yàn)的指令 required 必填 ngRequired 必填(ngRequired可以控制是否是必填校驗(yàn)) ngMinlength 最小長度...
摘要:為指令賦值函數(shù)名,即可運(yùn)行。它也是一個(gè)對象,指向應(yīng)用程序作用域內(nèi)的所有元素和執(zhí)行上下文。簡而言之,是與指令元素相關(guān)聯(lián)的當(dāng)前作用域,可以理解為視圖和控制器間的一個(gè)通道。它們被組織為模塊形式,之后可以被另一個(gè)引用。 Angularjs Angular是一款主旋律的MVVM框架,框架和傳統(tǒng)的庫不同: 類庫是一些函數(shù)的集合,它能幫助你寫WEB應(yīng)用。起主導(dǎo)作用的是你的代碼,由你來決定何時(shí)使用類...
閱讀 1386·2023-04-25 23:42
閱讀 2949·2021-11-19 09:40
閱讀 3565·2021-10-19 11:44
閱讀 3669·2021-10-14 09:42
閱讀 1918·2021-10-13 09:39
閱讀 3897·2021-09-22 15:43
閱讀 696·2019-08-30 15:54
閱讀 1490·2019-08-26 13:32