angular 指令 要點解析


指令可以刪繁就簡前端的js代碼,杜絕重復的js代碼和html代碼。

下面就對指令的重要屬性進行羅列

 

一、restrict  定義指令的出現形式

   可以定義為多種形式,比如 restrict = 'AE' 標識可以是屬性,也可以是元素。restrict  =  'AECM' 則標識支持下面所有形式

  • Attribute 屬性: <div my-directive=”exp”></div>
  • Element 元素: <my-directive></my-directive>
  • Class : <div class=”my-directive:exp;”></div>
  • M 注釋:<!-- directive: my-directive exp -->

 鑒於瀏覽器兼容問題。推薦 restrict  =  'A'

 

二、scope 作用域,與值綁定

  scope  = true/false/{name:'=/@/&'}   

  默認為false,如果設置為true 則說明指令內部獨立作用域。

  scope: {
      lover: '=',    name: '@',    say: '&'   }

  1、{name:'@inputName'} name 指 指令中作用域中scope.name , inputName 可不寫。默認綁定屬性name。eg:<directive inputName="小明-{{data.class}}"> 

  

  2、= 雙向綁定比較常用

  如:<lover="綁定內容"> 綁定內容可以理解為指令外部scope環境中的所有。它已經不是字符串的意義。甚至比如一個function的引用。 lover="sayChange" 那么love()就執行scope.sayChange(),如果scope.sayChange是對象、那么lover改變與sayChange改變均會聯動修改關聯的對方。

 

  3、”&“:綁定 Contoller中對應$scope上的函數。

 

 

三、template/templateUrl

  模板,該指令內部會被改html所代替, 如果設置了replace =true ,則outerHtml也會被移除。(會影響改標簽后面的其他指令)

 

 

四、combine編譯階段 提供兩個參數element,attrs。

  可以對當前元素做一些操作。返回link方法或者什么prelink等等。細節不說了。感覺用的也不多。 此處存在一個小bug 這個階段給element添加進去的html包含{{}} 到后面不會執行。但是加上 template=“”,就可以解決

 

 

五、link 參數為 scope ,element,attrs ,ctrl  ( ctrl 當  require = ngController才會有) 

  如果有combine,link需要作為combine的return 對象。

  link require="ngModel",則可以拿到ngModelController,那么Ctrl就可以有很多的擴展點,這也是我要寫本文的目的所在。其他事不過走走過場而已。

 

  ngModel對於值有兩個重要的概念叫modelValue,和viewValue  見名知意,我們可以理解為數據庫持久化值為ModelValue而最終展示到UI上給用戶看到的是viewValue。他們可以不同。

  1、ctrl.$formatters 格式化鏈 ngModel 的 ModelValue to ViewVlaue過程中需要有序執行的一串 function,

    那就太方便了。比如擴展格式化:日期、金額格式化;校驗:假如modelValue不合法、則不會展示到前端。

  2、 ctrl.$parsers 解析鏈 ngModel 的 ViewValue to ModelValue過程中需要執行的一串function

    同樣在 反格式化的處理:金額去除¥符號轉為數字;校驗不合法的數據無法提交給ModelView,(不提交給ModelValue 其他對改字段監控變化就不會得到通知。   angular雙向綁定多么美妙的設計,)

  3、ctrl.$render 當視圖需要更新時執行

    比如checkbox viewValue改成了false,render會將原生checkbox 的checked=true,可以重新賦值修改該function

 

  最后提供幾個例子可以感受formatters ,parsers ,強大的擴展性。

  checkBox 數據庫值為逗號分隔 

 1 /**
 2  * @ht-boolean 可為空, 格式以“/”分割truevalue 和falsevalue 
 3  * <span  ht-boolean="Y/N" text="測試按鈕" ng-model="prop.skipFirstNode" ht-tip title="我是按鈕的提示"/>
 4  */
 5 .directive('htBoolean', function() {
 6     return {
 7         restrict : 'A',
 8         require:'ngModel',
 9         scope : true,
10         link : function(scope, element, attrs,ctrl) {
11             var booleanConf =attrs.htBoolean;
12             scope.text = attrs.text;
13             if(booleanConf)    booleanConf=booleanConf.split("/");
14             else             booleanConf = [true,false];
15             
16             var trueValue = booleanConf[0],falseValue = booleanConf[1];
17             
18             ctrl.$formatters.push(function(value){
19                 return value === trueValue;
20             });
21             
22             ctrl.$parsers.push(function(value){
23                 return value ? trueValue : falseValue;
24             });
25             
26             ctrl.$render = function(){
27                 scope.checked = ctrl.$viewValue;
28             };
29               
30             element.on('click', function(){
31                 scope.$apply(function() {
32                   scope.checked = !scope.checked;
33                   ctrl.$setViewValue(scope.checked);
34                 });
35             });
36         },
37         template:'<lable class="btn label-sm {{checked ? \'active\':\'inactive\'}}" >{{text}}</lable>'  
38     };
39 })
ht-boolean代替checkBox的自定義前端標簽。(針對true、false兩種狀態的指令) 體驗下$render的功能

 自定義表單校驗 擴展平台自有校驗

  

 六、controller($scope,element) 

 
  controller 先與combine執行。 

  

  

 最后推薦有些異常情況無法解決的同仁直接查看源碼,angular.js   @license AngularJS v1.2.19

 compileNodes 便是編譯DOM元素的方法,里面applyDirectivesToNode 為實際處理指令的方法。 跟一下相信就清楚了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM