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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值