溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Angular.JS中指令的參數(shù)有哪些

發(fā)布時(shí)間:2020-11-27 15:34:25 來(lái)源:億速云 閱讀:131 作者:Leah 欄目:移動(dòng)開(kāi)發(fā)

Angular.JS中指令的參數(shù)有哪些?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

指令的參數(shù)

angular.module('app', [])
.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: // 返回一個(gè)對(duì)象或連接函數(shù),如下所示:
 function(tElement, tAttrs, transclude) {
 return {
 pre: function(scope, iElement, iAttrs, controller) { ... },
 post: function(scope, iElement, iAttrs, controller) { ... }
 }
 return function postLink(...) { ... }
 }
 };
 });

把它們分成三類:

  1. 描述指令或DOM本身特性的內(nèi)部參數(shù)

  2. 連接指令外界、與其他指令或控制器溝通的對(duì)外參數(shù)

  3. 描述指令本身行為的行為參數(shù)

內(nèi)部參數(shù)

  • restrict:String,E(元素)<my-directive></my-directive> A(屬性,默認(rèn)值)<div my-directive="expression"></div> C(類名)<div class="my-directive:expression;"></div> M(注釋)<--directive:my-directive expression-->

  • priority: Number,指令執(zhí)行優(yōu)先級(jí)

  • template: String,指令鏈接DOM模板,例如“<h2>{{head}}</h2>”

  • templateUrl:String,DOM模板路徑

  • replace: Boolean,指令鏈接模板是否替換原有元素,

對(duì)外參數(shù)——scope

scope參數(shù)非常重要,本應(yīng)該是放到最后說(shuō)明的,但是scope卻是理解其他參數(shù)的關(guān)鍵,所以務(wù)必先跟大家說(shuō)清楚。

scope參數(shù)的作用是,隔離指令與所在控制器間的作用域、隔離指令與指令間的作用域。

scope參數(shù)是可選的,默認(rèn)值為false,可選true、對(duì)象{};

  • false:共享父域

  • true:繼承父域,且新建獨(dú)立作用域

  • 對(duì)象{}:不繼承父域,且新建獨(dú)立作用域

false、true、{}三者對(duì)比

來(lái)看個(gè)例子

<body>
 <div ng-controller='parentCtrl'>
 <h4>指令scope參數(shù)——false、true、{}對(duì)比測(cè)試</h4>
 parent:
 <div>
 <span> {{parentName}}</span>
 <input type="text" ng-model="parentName" />
 </div>
 <br />
 <child-a></child-a>
 <br />
 <child-b></child-b>
 <br />
 <child-c parent-name="parentName"></child-c>
 </div>
 <!--t1指令模板-->
 <script type="text/html" id="t1">
 <div>
 <span>{{parentName}}</span>
 <input type="text" ng-model="parentName" />
 </div>
 </script>
 <script>
 var app = angular.module("app", []);

 app.controller('parentCtrl', function ($scope) {
 $scope.parentName = "parent";
 })

 //false:共享作用域
 app.directive('childA', function () {
 return {
 restrict: 'E',
 scope: false,
 template: function (elem, attr) {
  return "false:" + document.getElementById('t1').innerHTML;
 }
 };
 });

 //true:繼承父域,并建立獨(dú)立作用域
 app.directive('childB', function () {
 return {
 restrict: 'E',
 scope: true,
 template: function (elem, attr) {
  return "true:" + document.getElementById('t1').innerHTML;
 },
 controller: function ($scope) {
  $scope.parentName = "parent";

  //已聲明的情況下,$scope.$watch監(jiān)聽(tīng)的是自己的parentName
  $scope.$watch('parentName', function (n, o) {
  console.log("child watch" + n);
  });

  //$scope.$parent.$watch監(jiān)聽(tīng)的是父域的parentName
  $scope.$parent.$watch('parentName', function (n, o) {
  console.log("parent watch" + n);
  });
 }
 };
 });

 //{}:不繼承父域,建立獨(dú)立作用域
 app.directive('childC', function () {
 return {
 restrict: 'E',
 scope: {},
 template: function (elem, attr) {
  return "{}:" + document.getElementById('t1').innerHTML;
 },
 controller: function ($scope) {
  console.log($scope);
 }
 };
 });

 </script>
</body>

false參數(shù)

本質(zhì):子域與父域共享作用域。

特點(diǎn):父域修改parentName的同時(shí),指令綁定的parentName的元素會(huì)被刷新。

Angular.JS中指令的參數(shù)有哪些 

反之,指令內(nèi)部parentName被修改時(shí),父域的parentName同樣會(huì)被刷新。

Angular.JS中指令的參數(shù)有哪些 

true參數(shù)

本質(zhì):子域繼承父域,并建立獨(dú)立作用域。

特點(diǎn):

1、在指令已聲明parentName的情況下,父域parentName變更,指令中parentName不會(huì)發(fā)生變化。
指令在true參數(shù)下,建立了的scope,獨(dú)立并隔離與父控制器的scope。

controller: function ($scope) {
 $scope.parentName = "parent";
}

Angular.JS中指令的參數(shù)有哪些

反之,指令中parentName變更,父域也不會(huì)發(fā)生變化。

Angular.JS中指令的參數(shù)有哪些 

2、在指令未聲明parentName的情況下,父域的parentName變更,指令中parentName也會(huì)刷新
這種情況很多時(shí)候會(huì)被忽略,指令的scope沒(méi)有聲明對(duì)象時(shí),其元素綁定的仍然是父域的對(duì)象。但,一旦指令中Input變更了,對(duì)應(yīng)的獨(dú)立scope也會(huì)自動(dòng)聲明該綁定對(duì)象,這就回到了第1種情況。

controller: function ($scope) {
 //$scope.parentName = "parent";
}

Angular.JS中指令的參數(shù)有哪些

然而,指令中parentName變更,父域是不會(huì)變化的;

Angular.JS中指令的參數(shù)有哪些 

3、在指令已聲明parentName的情況下 ,在指令中監(jiān)聽(tīng)父域parentName 的變化無(wú)效。但監(jiān)聽(tīng)子域parentName的變化有效
獨(dú)立子域scope,只能監(jiān)聽(tīng)自己的,不能監(jiān)聽(tīng)父域的。但通過(guò) $scope.$parent可以監(jiān)聽(tīng)父域。

controller: function ($scope) {
 $scope.parentName = "parent" ;

 //已聲明的情況下,$scope.$watch監(jiān)聽(tīng)的是自己的parentName
 $scope.$watch( 'parentName' , function (n, o) {
 console.log("child watch" + n);
 });

 //$scope.$parent.$watch監(jiān)聽(tīng)的是父域的parentName
 $scope.$parent.$watch( 'parentName' , function (n, o) {
 console.log("parent watch" + n);
 });
}

Angular.JS中指令的參數(shù)有哪些

4、在指令未聲明parentName的情況下 ,在指令中監(jiān)聽(tīng)父域parentName的變化有效。

這里就不解釋了,參考第2點(diǎn),大家可以動(dòng)手試一下。

controller: function ($scope) {
 //$scope.parentName = "parent";

 //未聲明的情況下,$scope.$watch監(jiān)聽(tīng)的是父域的parentName
 $scope.$watch('parentName' , function (n, o) {
 console.log("child watch" + n);
 });
}

對(duì)象{}參數(shù)

本質(zhì):子域不繼承父域,并建立獨(dú)立作用域。

特點(diǎn):

1、當(dāng)scope對(duì)象為空對(duì)象時(shí),無(wú)論是父域parentName,還是指令子域parentName發(fā)生變更,都不會(huì)影響到對(duì)方。
原理很清楚,就是指令建立的獨(dú)立作用域,與父域是完全隔離的。

scope: {}

Angular.JS中指令的參數(shù)有哪些 

2、當(dāng)scope對(duì)象為非空對(duì)象時(shí),指令會(huì)將該對(duì)象處理成子域scope的擴(kuò)展屬性。而父域與子域之間傳遞數(shù)據(jù)的任務(wù),就是可以通過(guò)這塊擴(kuò)展屬性完成。

<div ng-controller='parentCtrl'>
 parent:
 <p><span>{{name}}</span><input type="text" ng-model="name" /></p>
 <p><span>{{sexy}}</span><input type="text" ng-model="sexy" /></p>
 <p><span>{{age}}</span><input type="text" ng-model="age" /></p>
 <br />

 <!--特別注意:@與=對(duì)應(yīng)的attr,@是單向綁定父域的機(jī)制,記得加上{{}};&對(duì)應(yīng)的attrName必須以on-開(kāi)頭-->
 <child-c my-name="name" my-sexy-attr="sexy" my-age="{{age}}" on-say="say('i m ' + name)"></child-c>
</div>

<!--t1指令模板-->
<script type="text/html" id="t1">
 <div>
 <span>{{myName}}</span>
 <input type="text" ng-model="myName" />
 </div>
 <div>
 <span>{{mySexy}}</span>
 <input type="text" ng-model="mySexy" />
 </div>
 <div>
 <span>{{myAge}}</span>
 <input type="text" ng-model="myAge" />
 </div>
</script>

<script>
 var app = angular.module("app", []);

 app.controller('parentCtrl', function ($scope) {
 $scope.name = "mark";
 $scope.sexy = "male";
 $scope.age = "30";
 $scope.say = function (sth) {
  alert(sth);
 };
 })

 app.directive('childC', function () {
 return {
  restrict: 'E',
  scope: {
  myName: '=',
  mySexy: '=mySexyAttr',
  myAge: '@',
  onSay: '&'
  },
  template: function (elem, attr) {
  return "{}:" + document.getElementById('t1').innerHTML;
  },
  controller: function ($scope) {
  console.log($scope.myName);
  console.log($scope.mySexy);
  console.log($scope.myAge);
  $scope.onSay();
  }
 };
 });

</script>

@(or @Attr)綁定策略——本地作用域?qū)傩?,使用@符號(hào)將本地作用域同DOM屬性的值進(jìn)行綁定。指令內(nèi)部作用域可以使用外部作用域的變量。(單向引用父域?qū)ο螅?/p>

<child-c my-age="{{age}}"></child-c>

ps:@ 是單向綁定本地作用域,記得加上{{}}

scope: {  
 myAge: '@',
}

Angular.JS中指令的參數(shù)有哪些

= (or =Attr)綁定策略——雙向綁定:通過(guò)=可以將本地作用域上的屬性同父級(jí)作用域上的屬性進(jìn)行雙向的數(shù)據(jù)綁定。就像普通的數(shù)據(jù)綁定一樣,本地屬性會(huì)反映出父數(shù)據(jù)模型中所發(fā)生的改變。(雙向引用父域?qū)ο螅?/p>

<child-c onSay="name"></child-c>

ps:=策略不需要加上{{}}進(jìn)行綁定

scope: {  
 myName: '=',
}

Angular.JS中指令的參數(shù)有哪些

& (or &Attr)綁定策略——通過(guò)&符號(hào)可以對(duì)父級(jí)作用域進(jìn)行綁定,以便在其中運(yùn)行函數(shù)。(調(diào)用父域函數(shù))

<child-c on-say="say('i m ' + name)"></child-c>

ps:&對(duì)應(yīng)的attrName必須以on-開(kāi)頭

scope: {  
 onSay: '&',
}

父域綁定調(diào)用函數(shù)及傳參

app.controller('parentCtrl', function ($scope) {
 $scope.say = function (sth) {
  alert(sth);
 };
})

Angular.JS中指令的參數(shù)有哪些

ps特別注意:@與=對(duì)應(yīng)的attr,;

<child-c my-name="name" my-sexy-attr="sexy" my-age="{{age}}" on-say="say('i m ' + name)"></child-c>

總結(jié)下來(lái),scope擴(kuò)展對(duì)象,既能夠解耦父域與子域共域的問(wèn)題,也能夠?qū)崿F(xiàn)指令與外界通訊的問(wèn)題,是Angular開(kāi)發(fā)指令化模塊化的重要基礎(chǔ)。在往后的章節(jié),我會(huì)向大家介紹指令化開(kāi)發(fā)的更多實(shí)例。

對(duì)外參數(shù)——require

scope是指令與外界作用域通訊的橋梁,而require是指令與指令之間通訊的橋梁。這個(gè)參數(shù)最大的作用在于,當(dāng)要開(kāi)發(fā)單指令無(wú)法完成,需要一些組合型指令的控件或功能,例如日期控件,通過(guò)require參數(shù),指令可以獲得外部其他指令的控制器,從而達(dá)到交換數(shù)據(jù)、事件分發(fā)的目的。

使用方法:require: String or Array——String值為引入指令名稱,并且有兩個(gè)尋找指令策略符號(hào)‘?'與‘^';Array數(shù)組則為多個(gè)外部指令名稱。

在link函數(shù)第4個(gè)參數(shù)ctrl中獲取注入外部指令的控制器,如果require為String,ctrl為對(duì)象,如果require是數(shù)組,ctrl為數(shù)組。

require: '^teacher1',
link: function ($scope, $element, $attrs, ctrl) {
 //ctrl指向teacher1指令的控制器
}

?策略——尋找指令名稱,如果沒(méi)有找到,link函數(shù)第4個(gè)參數(shù)為null;如果沒(méi)有?,則報(bào)錯(cuò)。

Angular.JS中指令的參數(shù)有哪些 

^ 策略——在自身指令尋找指令名稱的同時(shí),向上父元素尋找;如果沒(méi)有^,則僅在自身尋找。
如下例子,指令studentA向上可以找到指令teacher及自身,但是不能找到相鄰兄弟的student-b。

<div teacher>
 <student-a></student-a>
 <student-b></student-b>
</div>

完整例子

<body>
 <div teacher>
 {{name}}
 <student-a></student-a>
 <student-b></student-b>
 </div>
 <script>
 var app = angular.module("app", []);

 //studentA——require指向父級(jí)指令teacher
 app.directive('studentA', function () {
  return {
  require: '?^teacher',
  scope: {},
  template: '<div>A`s teacher name: <span>{{teacherName}}</span></div>',
  link: function ($scope, $element, $attrs, ctrl) {
   //獲取teacher指令控制器,并調(diào)用其方法sayName()
   $scope.teacherName = ctrl.sayName();
  }
  };
 });

 //studentB——require指向父級(jí)指令teacher,及指令studentA
 //但是,由于不能獲得兄弟,也沒(méi)有采取?策略,導(dǎo)致報(bào)錯(cuò)
 app.directive('studentB', function () {
  return {
  require: ['?^teacher', 'studentA'],
  scope: {},
  template: '<div>B`s teacher name: <span>{{teacherName}}</span></div>',
  link: function ($scope, $element, $attrs, ctrl) {
   $scope.teacherName = ctrl.sayName();
  }
  };
 });

 app.directive('teacher', function () {
  return {
  restrict: 'A',
  controller: function ($scope) {
   $scope.name = "Miss wang";

   //擴(kuò)展控制器的方法sayName,目的是讓外部?jī)?nèi)獲取控制器內(nèi)部數(shù)據(jù)
   this.sayName = function () {
   return $scope.name;
   };
  }
  };
 });
 </script>
</body>

Angular.JS中指令的參數(shù)有哪些

既然require可以獲取外部指令,那Angular原生指令應(yīng)該也是能夠獲取。其中最廣泛應(yīng)用的就是require: 'ngModel',關(guān)于ngModel在自定義指令上的應(yīng)用,留待下回實(shí)例中再跟大家深入討論。

行為參數(shù)——link與controller

為什么要把link與controller兩個(gè)參數(shù)放到一起?

因?yàn)楹芏嗤瑫?huì)把它們錯(cuò)誤地混淆使用,包括我自己。

link與controller都是描述指令行為的參數(shù),但它們是要描述的行為是完全不同的類型。

controller語(yǔ)法 controller:String or Function

controller本身的意義就是賦予指令控制器,而控制器就是定義其內(nèi)部作用域的行為的。

所以controller要描述的是:指令的作用域的行為。

//指向匿名控制器
controller: function ($scope) {
},
//指向控制器mainCtrl
controller: "mainCtrl"

link語(yǔ)法 link:String Or Function

link名稱是鏈接函數(shù),啥意思,好像挺難理解。所以在解釋鏈接函數(shù)之前,先要說(shuō)一下Angular的初始化對(duì)于指令究竟做了什么。

Angular在剛從HTTP Response接收靜態(tài)素材之初,會(huì)首先去分析母頁(yè)HTML中有哪些原生指令或自定義指令,然后再去加載指令的template模板HTML,而template模板中又去加載自己的指令模板,如此類推,直到Angular找到了所有的指令及模板,形成模板樹(shù),并返回模板函數(shù),提供給下一階段進(jìn)行數(shù)據(jù)綁定。

<body>
 <stu1 ></ stu1>
 <script >
  var app = angular.module("app" , []);

  app.directive( 'stu1' , function () {
   return {
    restrict: 'E' ,
    template: "<p>1</p><stu2></stu2>" ,
    link: function (scope) {
     console.log( 'stu1 running' );
    }
   };
  });

  app.directive( 'stu2' , function () {
   return {
    restrict: 'E' ,
    template: "<p>2</p><stu3></stu3>" ,
    link: function (scope) {
     console.log( 'stu2 running' );
    }
   };
  });

  app.directive( 'stu3' , function () {
   return {
    restrict: 'E' ,
    template: "<p>3</p>" ,
    link: function (scope) {
     console.log( 'stu3 running' );
    }
   };
  });

 </script >
</ body>

 
console output

stu3 running
stu2 running
stu1 running

Angular.JS中指令的參數(shù)有哪些

注意以上例子,在第一個(gè)斷點(diǎn)stu3 running的時(shí)候,1 2 3 三個(gè)模板都渲染完成了。然后從最根部的stu3的link函數(shù)開(kāi)始,依次執(zhí)行stu 3 stu2 stu1的link函數(shù)。

簡(jiǎn)單來(lái)說(shuō)就是:

  1. 加載模板,形成DOM模板樹(shù)

  2. @@@@

  3. 數(shù)據(jù)綁定

@@@@是啥?沒(méi)錯(cuò),就是link鏈接函數(shù),它會(huì)在形成模板樹(shù)之后,在數(shù)據(jù)綁定之前,從最底部指令開(kāi)始,逐個(gè)指令執(zhí)行它們的link函數(shù)。

在這個(gè)時(shí)間節(jié)點(diǎn)的link函數(shù),操作DOM的性能開(kāi)銷是最低,非常適合在這個(gè)時(shí)機(jī)執(zhí)行DOM的操作,例如鼠標(biāo)操作或觸控事件分發(fā)綁定、樣式Class設(shè)置、增刪改元素等等。

所以link就是描述指令元素操作行為。

link: function (scope, element, attr, ctrl) {

 element.bind("click", function () {
  console.log("綁定點(diǎn)擊事件");
 });

 element.append("<p>增加段落塊</p>");

 //設(shè)置樣式
 element.css("background-color", "yellow");

 //不推薦,在link中賦予scope行為
 scope.hello = function () {
  console.log("hello");
 };
}

同理,在link中定義$scope行為是不推薦的。

這樣想想,對(duì)于controller與link,就明白了。但還有一個(gè)問(wèn)題,它們倆的執(zhí)行順序是?答案是先controller,后link。

放到全局順序就是:

  1. 執(zhí)行controller,設(shè)置各個(gè)作用域scope

  2. 加載模板,形成DOM模板樹(shù)

  3. 執(zhí)行l(wèi)ink,設(shè)置DOM各個(gè)行為

  4. 數(shù)據(jù)綁定,最后scope綁上DOM

例子

 <div student>
  {{name }}
 </div>
 <script>
  var app = angular.module("app", []);

  app.directive('student', function () {
   return {
    restrict: 'A',
    controller: function ($scope) {
     $scope.name = "tgor";

     console.log('controller running');
    },
    link: function (scope, el) {
     el.append("<p>hello</p>");

     console.log('link running');
    }
   };
  });

 </script>

Angular.JS中指令的參數(shù)有哪些

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI