关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » UI前端 »AngularJS 的 scope 选项与绑定策略

    AngularJS 的 scope 选项与绑定策略

    2015-05-02 00:00:00 出处:无上@诀
    分享

    开门见山地说,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 }}”;其实,另外两个符号=和&也有这样的简写规则,方便起见接下来都使用这种写法。

    @到此为止,接下来就是’='了。=与@的不同点在于,@是针对字符串(准确来说是表达式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)。这其中的道理跟无参的例子是大同小异的。

    总结:

    为什么Angular要为我们提供这样一套绑定策略呢?就是因为它想让我们在为指令创建隔离作用域的同时,还能访问到父级中的属性,这就像,你在隔离作用域身上打了一个洞,然后用一条管道,把指令内部和外界的属性给连起来(绑定),并且一切的通信都只能通过这条管道来实行。这是我目前能做到的最深刻的理解了,可能还有需要的补充和纠正的地方,希望大家能抽空指点我一下,感激不尽!

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。