开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细记录的。但是这显然不符合实际开发中的需求,因为实际上,我们经常想要我们的指令能够在特定的情况下与外界进行数据上的交互,这就需要借助绑定策略之手了。

大家知道,当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 }}";其实,另外两个符号=和&也有这样的简写规则,方便起见接下来都使用这种写法。

@到此为止,接下来就是'='了。=与@的不同点在于,@是针对字符串而用,但=是针对某个对象的引用,

这么说可能不太专业,但就拿上边的例子而言,我们在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)。这其中的道理跟无参的例子是大同小异的。

AngularJS学习笔记之directive——scope选项与绑定策略的更多相关文章

  1. AngularJS学习笔记之directive—scope选项与绑定策略

    From:http://www.linuxidc.com/Linux/2015-05/116924.htm scope:{}使指令与外界隔离开来,使其模板(template)处于non-inherit ...

  2. Angular中directive——scope选项与绑定策略,这个也经常迷惑的。

    开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细 ...

  3. angularjs学习笔记三——directive

    AngularJS 通过被称为 指令 的新属性来扩展 HTML. 正如你所看到的,AngularJS 指令是以 ng 作为前缀的 HTML 属性. HTML5 允许扩展的(自制的)属性,以 data- ...

  4. angularjs学习笔记3-directive中scope的绑定修饰符

    在angularjs中,一个directive返回一个对象,对象存在很多属性,并且可以在directive中自定义自己的scope,而使用自己的scope是为了防止一个directive被使用在多个地 ...

  5. AngularJS学习笔记(三)数据双向绑定

    双向绑定 双向绑定是AngularJS最实用的功能,它节省了大量的代码,使我们专注于数据和视图,不用浪费大量的代码在Dom监听.数据同步上,关于双向更新,可看下图: 下面,我们通过代码来实现.先不要纠 ...

  6. AngularJS学习笔记(一) 关于MVVM和双向绑定

    写在前面: 因为需要开始学习ng,之前在知乎上听大神们介绍ng的时候说这个坑如何的大,学了一阵(其实也就三天),感觉ng做的很大很全,在合适的情境你可以完全使用ng搞定一切.这一点从诸如jqLite之 ...

  7. AngularJs学习笔记--directive

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/directive Directive是教HTML玩一些新把戏的途径.在DOM编译期间,directiv ...

  8. AngularJs学习笔记--Scope

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/scope 一.什么是Scope? scope(http://code.angularjs.org/1. ...

  9. AngularJs学习笔记--Understanding the Controller Component

    原版地址:http://docs.angularjs.org/guide/dev_guide.mvc.understanding_model 在angular中,controller是一个javasc ...

随机推荐

  1. java中遍历map的几种方法介绍

          喜欢用Java写程序的朋友都知道,我们常用的一种数据结构map中存储的是键值对,我们一般存储的方式是: map.put(key, value); 而提取相应键的值用的方法是: map.ge ...

  2. 错误 frm-40654 记录已经被另一个用户更新,重新查询以查看修改

     导致这问题的原因有多个,有些是最近在项目上发现不同于网上其他人遇到的 网上一般来说大家都说有如下几个原因.但是在项目上做返利时 对AP invoice 的有做更改,导致更改或插入的数据在界面上修 ...

  3. redhat安装vsftpd

    一个小问题 rpm -qa|ftp 但是出现3个ftp 只安装了一个 关于网卡ip 首先,我们看到 网卡上面有个x 说明网络是有问题的 我们双击,看到 我们先把connected和connect at ...

  4. 【一天一道LeetCode】#112. Path Sum

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  5. iOS中 Swift初级入门学习(三)

    // // main.swift // LessonSwift-03 // // Copyright (c) 2015年 韩俊强. All rights reserved. // import Fou ...

  6. Uva - 1598 - Exchange

    本来想用优先队列做,可是不知道怎么处理之间的关系,最后还是用了map方法AC了,不过速度上有些慢,提交的时候跑了1.557秒.估计这道题时间都稍微长些,题目的时间限制也是4.5秒,不像一般题目的3秒限 ...

  7. (NO.00002)iOS游戏精灵战争雏形(八)

    子弹的初始化工作前2篇基本做好了,下面就是如何射出子弹. 通常来说,子弹射向目标对象,需要走一条直线.直线由2点定位,分别为发射点和目标点. 发射点就是开枪精灵自身的位置,目标点则为敌方精灵的位置,大 ...

  8. 【一天一道LeetCode】#42. Trapping Rain Water

    一天一道LeetCode系列 (一)题目 Given n non-negative integers representing an elevation map where the width of ...

  9. [Ext.Net]动态生成控件(二)--js动态添加文本框

    转自:http://www.ext.net.cn/forum.php?mod=viewthread&tid=11931 点击一个按钮就出现一行控件,点击删除控件就可将一行控件删除,这是不是你一 ...

  10. 【Android 应用开发】 Ubuntu 安装 Android Studio (旧版本|仅作参考)

    . 果断换Ubuntu了, Ubuntu的截图效果不好, 不能设置阴影 ... 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article ...