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

    上一篇返回首页 下一篇

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

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

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

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

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

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