Angualr指令中的scope

directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性。通常使用这种直接共享的方式可以实现一些简单的 directive 功能。

但是,当你要创建一个可以重复使用的directive的时候,就不能依赖于父scope了,因为在不同的地方使用directive对应的父scope不一样。

所以你需要一个隔离的scope,我们可以向下面这样来定义我们的scope。

复制代码
module1.directive("testDirective", function () {
        return {
            scope: {
                value: '提莫队长正在待命!'
                         },
            template: 'Say:{{value}}'
        }
});             
复制代码

这样就很方便的将我们directive的上下文scope给定义出来了,但是,如果我想将父scope中的属性传递给directive的scope怎么办呢?

directive 在使用隔离 scope 的时候,提供了三种方法同隔离之外的地方交互:

  • @ 绑定一个局部 scope 属性到当前 dom 节点的属性值。结果总是一个字符串,因为 dom 属性是字符串。
  • & 提供一种方式执行一个表达式在父 scope 的上下文中。如果没有指定 attr 名称,则属性名称为相同的本地名称。
  • = 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。

以上三种方式都要在directive的attr属性中进行赋值。上面的话理解起来比较困难,我根据自己的理解做了一下修改:

@:只能绑定字符串,所以一些简单的继承父scope的属性使用@
=: 需要实现双向数据绑定的时候使用=
&: 提供一种方式执行一个表达式在父scope的上下文中,即使用于将父scope中的函数绑定在指令的scope中

以上的理解也许有些偏颇,欢迎指正。

(1)先说@

复制代码
app.controller("ctl1", function ($scope) {
        $scope.name = "hello world";
    }).directive("testDirective", function () {
        return {
            scope: {
                name: "@"
            },
            template: 'Say:{{name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">'
        }
})
复制代码
复制代码
<div ng-controller="ctl1">
   <div>
       <div>父scope:
           <div>Say:{{name}}<br>改变父scope的name:<input type="text" value="" ng-model="name"/></div>
       </div>
       <div>隔离scope:这个显示为hello world
           <div test-directive name="{{name}}"></div>
       </div>
        <div>隔离scope(不使用{{name}}这个就直接显示为name了):
             <div test-directive name="name"></div> 
         </div>
   </div>
复制代码

我们在test-directive指令所在的div上面,增加了一个name属性,要使用双花括号来给属性赋值。也可以写成nameCopy:'@nameForCtl',这样写,在给directive中的scope的属性赋值的时候,获取查询@后面的name这个标识对应的属性的值(这里nameForCtl在js中是驼峰写法,同样的在html中对应的属性名应该写成name-for-ctl)。不是很推荐这种写法,感觉有点多余。

(2)=

上一个例子中,我们使用name="{{name}}"的形式来传递父scope 的属性对应的值,so,我们只是把对应的值传递给了directive的scope,当我想实现在directive中改变父scope传递过来的值时,父scope中的值也对应的改变,显然用@这种方法走不通。

这时=就派上用场了。

复制代码
 app.controller("ctl1", function ($scope) {
        $scope.user = {
            name: 'hello',
            id: 1
        };
    }).directive("testDirective", function () {
        return {
            scope: {
                user: "="
            },
            template: 'Say:{{user.name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="user.name"/>'
        }
    })
复制代码
复制代码
<div ng-controller="ctl1">
    <div>父scope:
        <div>Say:{{user.name}}<br>改变父scope的name:<input type="text" value="" ng-model="user.name"/></div>
    </div>
    <div>隔离scope:
        <div isolated-directive user="user"></div>
    </div>
    <div>隔离scope(使用{{name}},这个会报错):
        <div isolated-directive user="{{user}}"></div> 
    </div>
</div>
复制代码

这一个例子和上一个例子不同的地方就是属性赋值的时候,一个应该使用{{}},一个不该使用。=为了实现双向数据绑定,angular会使用‘=’对应的属性的值与父scope中的属性进行匹配,然后传递给diractive中的scope。至于实现的细节和原理,这里我就不说了(其实是不大清楚)。

(3)&

& 方式提供一种途经使directive 能在父 scope 的上下文中执行一个表达式。此表达式可以是一个 function。其实说白了,就是可以使用在父scope中定义的函数。

比如:当你写了一个 directive,当用户点击按钮时,directive 想要通知 controller,controller 无法知道 directive 中发生了什么,也许你可以通过使用 angular 中的 event 广播来做到,但是必须要在 controller 中增加一个事件监听方法。
最好的方法就是让 directive 可以通过一个父 scope 中的 function,当 directive 中有什么动作需要更新到父 scope 中的时候,可以在父 scope 上下文中执行一段代码或者一个函数。

复制代码
 app.controller("ctl1", function ($scope) {
        $scope.value = "hello world";
        $scope.click = function () {
            $scope.value = Math.random();
        };
    }).directive("testDirective", function () {
        return {
            scope: {
                action: "&"
            },
            template: '<input type="button" value="在directive中执行父scope定义的方法" ng-click="action()"/>'
        }
    })
复制代码
复制代码
<div  ng-controller="ctl1">
        <div>父scope:
            <div>Say:{{value}}</div>
        </div>
        <div>隔离scope:
            <div isolated-directive action="click()"></div>
        </div>
</div>
复制代码

在上面的例子中,我们的属性action赋值为一个方法:action="click()",这样一写,一眼就看出来是个什么东西了,好像也没什么好解释的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值