Angular學習心得之directive——scope選項與綁定策略

大家知道,當scope選項寫爲scope:{}這種形式的時候,就已經爲指令生成了隔離作用域,現在,我們來看看綁定策略的三種形式:& 、= 、@。

首先是@,它將本地作用域和DOM中的屬性值綁定起來(且這個屬性的值必須是父級作用域中的),什麼意思呢?說的簡單一點就是假設你在模板中有個雙花括號表達式,然後我們把表達式裏的內容和html中指令裏特定名字的屬性綁定起來,還是不懂?看看下面的代碼:

JS代碼:

directive("direct",function(){

        return{

            restrict: 'ECMA',

            template: '<div>指令中:{{ name }}</div>',

            scope:{

              name:'@forName'

            }
         } 
  })
.controller("nameController",function($scope){
      $scope.Name="張三"; 
});

HTML代碼:

<div ng-controller="nameController">
   <direct for-name="{{ Name }}"></direct>
<div>

運行結果可想而知,{{ name }}成功地與父控制器中的Name綁定起來了。當然這裏也可以這樣寫name:'@' 這樣寫的話,就默認DOM中的屬性名爲name了意即 for-name="{{ Name }}"可簡寫爲name="{{ Name }}";其實,另外兩個符號=和&也有這樣的簡寫規則,方便起見接下來都使用這種寫法。
@到此爲止,接下來就是'='了。=與@的不同點在於,@是針對字符串(準確來說是表達式expression)而用,但=是針對某個對象的引用;

這麼說可能不太專業,但就拿上邊的例子而言,我們在html中,把Name這個字符串通過一對雙花括號傳遞給for-name屬性,但如果我們用了=,這裏傳入的Name就不應該是一個字符串,而是一個對象的引用。這不是一個很一目瞭然的概念,所以我用接下來的兩個例子詮釋它的含義。

第一個例子:數組中的對象的引用

JS代碼:

directive("direct",function(){


        return{


            restrict: 'ECMA',


            template: '<div>指令中:{{ case.name }}</div>',


            scope:{


              case:'='


            }

         } 

  })

.controller("nameController",function($scope){

      $scope.data=[{name:"張三"},{name:"李四"}]; 

});

HTML代碼:

<div ng-controller="nameController">

   <direct case="data[0]"></direct>

   <direct case="data[1]"></direct> 
<div>

結果就是,一個張三,一個李四。這個例子中,data是一個對象數組,裏面包含了兩個對象,所以,我們分別把兩個對象傳遞給了case這個屬性,case屬性就把這個對象的引用傳遞給了模板中我們寫的{{ case.name }}中的case;而如果你在=後邊加上了自己定義的名字,那隻要把html裏case屬性換成那個名字就可以了。

第二個例子:經典的雙向輸入框

按照Angular的入門案例,創建兩個雙向綁定的輸入框,最簡單的實現方式就是:

<input ng-model="test"/>
 <input ng-model="test"/>

使用ng-model指令就可以做到了。接着,我們在自己的指令中實現這個效果。

JS代碼:

directive("direct",function(){



        return{



            restrict: 'ECMA',



            template: '<div>指令中:<input ng-model="model"/></div>',



            scope:{



              model:'='



            }


         } 


  })

.controller("nameController",function($scope){


      $scope.data=[{name:"張三"},{name:"李四"}]; 


});

HTML代碼:

<div ng-controller="nameController">

        父級scope中:<input ng-model="mark"/>

        <direct model="mark"/></direct>
 </div>

這就完成了,其實只不過是加了一點小把戲,把ng-model換成了model而已。

注意到,這兩個例子中,都是使用對象的引用,而不是單純的字符串,這也是=可以進行雙向綁定的關鍵。

最後是&符號。它的含義是:對父級作用域進行綁定,並將其中的屬性包裝成一個函數,注意,是屬性,意即,任何類型的屬性都會被包裝成一個函數,比如一個單純的字符串,或是一個對象數組,或是一個函數方法。

如果是字符串、對象數組和無參的函數,那麼可想而知,它們都會被包裝成一個無參的函數,若是有參的函數方法則反之,並且我們需要爲其傳入一個對象。現在,分別針對有參和無參兩種情況舉例。

無參情況

JS代碼:

.directive("direct",function(){




        return{

            restrict: 'ECMA',

            template: '<div>{{ title }}</div>'+'<div><ul><li ng-repeat="x in          contents">{{ x.text }}</li></ul></div>',

            scope:{

              getTitle:'&', 
              getContent:'&'             
         },
            controller:function($scope){ 
               $scope.title=$scope.getTitle();     //調用無參函數  
               $scope.contents=$scope.getContent();    //調用無參函數 
           } 
      } 
 })


.controller("nameController",function($scope){

    $scope.title="標題";

    $scope.contents =[{text:1234},{text:5678}]; 
});

HTML代碼:

<div ng-controller="nameController">
      <direct get-title="title" get-content="contents"></direct> 
  </div>

這個例子有幾個注意點:

1.指令的本地屬性(即模板裏花括號中的屬性)需要從本地取值,所以使用了controller選項,而在controller選項中,兩個無參方法分別返回了父級scope中的title字符串和contents對象數組。

2.在HTML中,我們把設置了get-title和get-content的屬性值爲title和contents,這實際上就完成了與父級scope的綁定,因爲我們纔可以從那兒取得實質的內容。

OK,有參情況

JS代碼:

.directive("direct",function(){ 
return{
            restrict: 'ECMA',
            template: '

<div><input ng-model="model"/></div>

'+'

<

div><button ng-click="show({name:model})">show</button>',
            scope:{
                show:'&'              
            }                      
         }
    })

    .controller("nameController",function($scope){
        $scope.showName=function(name){ 

          alert(name); 
         } 
     });

HTML代碼:

<div ng-controller="nameController">

      <direct show="showName(name)"></direct> 

  </div>

這個例子中,通過模板中的ng-click觸發了show函數並將一個叫做model的對象作爲name參數傳遞了進去,而在html中,我們把show的屬性值設爲showName(name)。這其中的道理跟無參的例子是大同小異的。



源引:https://segmentfault.com/a/1190000002758332

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