angularjs中指令的scope

当angularjs指令创建时面临的一个问题就是作用域的创建,也就是指令的scope。

angularjs提供了三种选择,体现在定义指令时的scope参数上,true,false,{}. 默认false;

scope = false

看代码

<!DOCTYPE html>
<html>
    <head>
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="bootstrap.min.css">
        <script src="angular.min.js"></script>
        <script src="bootstrap.min.js"></script>
        <script type="text/javascript">
            var myapp = angular.module("myapp", []);
            myapp.controller("MyController", ['$scope', function($scope) {
                $scope.name = "mario";
            }]);
            myapp.directive("myDirective", function() {
                return {
                    restrict: "AE",
                    scope: false,
                    replace: true,
                    template: "<div>" +
                        "<h1>下面部分是创建的指令生成的</h1>" +
                        "我的名字是:<span ng-bind='name'></span><br/>" +
                        "<input type='text' ng-model='name'><br/>" +
                        " </div>"
                }
            });
        </script>
    </head>
    <body ng-app="myapp">
        <div class="container" ng-controller="MyController">
            <div>
                我的名字是:<span ng-bind="name"></span>
                <br/>
                <input type="text" ng-model="name" />
            </div>
            <div my-directive></div>
        </div>
    </body>
</html>


可以看到指令scope直接使用了父作用域中的属性,当然方法也一样。可以理解为继承了父作用域中的属性方法,或者说也许他们就是同一个作用域。不管哪边发生变化,另一边都会发生变化。


scope = true

将上面false改为true, 可以发现,父作用域name改变,指令scope中的name改变,当然这有一个前提,那就是你还没去改变过指令scope中name的值。一旦改变就不起作用了。 而当你先去改变指令scope中的值可以发现父作用域中的name并没有改变。可以理解为指令创建了一个新的作用域,并且使用父scope中的值初始化了其中的值,而这个可以一直持续到你去改变指令scope中变量de值。


scope = {}

当我们将 scope设置为 {}时,意味着我们创建的一个新的与父作用域隔离的新的作用域,这使我们在不知道外部环境的情况下,就可以正常工作,不依赖外部环境。

<!DOCTYPE html>
<html>
    <head>
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="bootstrap.min.css">
        <script src="angular.min.js"></script>
        <script src="bootstrap.min.js"></script>
        <script type="text/javascript">
            var myapp = angular.module("myapp", []);
            myapp.controller("MyController", ['$scope', function($scope) {
                $scope.name = "mario";
                $scope.age = 23;
                $scope.changeAge = function() {
                    $scope.age = 19;
                }
            }]);
            myapp.directive("myDirective", function() {
                return {
                    restrict: "AE",
                    scope: {
                        name : '@myName',
                        age : '=age',
                        change : '&change'
                    },
                    replace: true,
                    template: "<div>" +
                        "<h1>下面部分是创建的指令生成的</h1>" +
                        "我的名字是:<span ng-bind='name'></span><br/>" +
                        "<input type='text' ng-model='name'><br/>" +
                        "我的age是:<span ng-bind='age'></span><br/>" +
                        "<input type='text' ng-model='age'><br/>" +
                        "<button class='btn btn-small btn-primary' ng-click='change()'>修改年龄</button>" +
                        " </div>"
                }
            });
        </script>
    </head>
    <body ng-app="myapp">
        <div class="container" ng-controller="MyController">
            <div>
                我的名字是:<span ng-bind="name"></span>
                <br/>
                <input type="text" ng-model="name" />
                <br/>
                我的age是:<span ng-bind="age"></span>
                <br/>
                <input type="text" ng-model="age" />
            </div>
            <div my-directive my-name="{{name}}" age="age" change="changeAge()"></div>
        </div>
    </body>
</html>

使用了隔离的作用域,不代表我们不可以使用父作用域的属性和方法。

  1. 我们可以通过向scope{}中传入特殊的前缀标识符(即prefix),来进行数据的绑定。
  2. 创建了隔离的作用域,我们可以通过@,&,=引用应用指令的元素的属性,如上面的代码那样,我们可以在scope: {
                            name : '@myName',
                            age : '=age',
                            change : '&change'
                        }   中,利用前缀标识符引用<div my-directive my-name="{{name}}" age="age" change="changeAge()"></div>中my-name, change,age
    这些属性的值。

下面我们来看看如何使用这些前缀标识符:

@

这是一个单项绑定的前缀标识符
使用方法: @myName驼峰写法对应my-name属性中的{{name}},  {{}}不可少,name是父scope中的模型

注意,属性的名字要用-将两个单词连接

=

这是一个双向数据绑定前缀标识符
使用方法:写法和上面差不多,不需要{{}}


另外,如果指令scope参数中key:value 同名可省略

上面的scope: {
                        name : '@myName',
                        age : '=age',
                        change : '&change'
                    }  

也可以写成

scope: {
                        name : '@myName',
                        age : '=',
                        change : '&'
                    }  


my-name以及age属性也可以跟普通字符串,那么指令scope中模型也将被赋予相应de属性值。

&

这是一个绑定函数方法的前缀标识符
使用方法: 需要注意的是属性值写成调用方法的形式,change="changeAge()"


进一步说明,我们的指令是如何利用这些前缀标识符来寻找我们想要的属性或者函数的

  • @ 当指令编译到模板的name时,就会到scope中寻找是否含有name的键值对,如果存在,就像上面那样,看到@就知道这是一个单向的数据绑定,然后寻找原来的那个使用指令的元素上(或者是指令元素本身)含有这个值的属性即my-name={{name}},然后在父作用域查找{{name}}的值,得到之后传递给模板中的name
  • =&@差不多,只不过=进行的是双向的数据绑定,不论模板还是父作用域上的属性的值发生改变都会使另一个值发生改变,而&是绑定函数而已。

在附带一个&中函数有参数时的调用

<!DOCTYPE html>
<html>
    <head>
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="bootstrap.min.css">
        <script src="angular.min.js"></script>
        <script src="bootstrap.min.js"></script>
        <script type="text/javascript">
            var myapp = angular.module("myapp", []);
            myapp.controller("MyController", ['$scope', function($scope) {
                $scope.name = "mario";
                $scope.age = 23;
                $scope.changeAge = function(age) {
                    $scope.age = age;
                }
            }]);
            myapp.directive("myDirective", function() {
                return {
                    restrict: "AE",
                    scope: {
                        name : '@myName',
                        age : '=',
                        change : '&'
                    },
                    replace: true,
                    template: "<div>" +
                        "<h1>下面部分是创建的指令生成的</h1>" +
                        "我的名字是:<span ng-bind='name'></span><br/>" +
                        "<input type='text' ng-model='name'><br/>" +
                        "我的age是:<span ng-bind='age'></span><br/>" +
                        "<input type='text' ng-model='age'><br/>" +
                        "<button class='btn btn-small btn-primary' ng-click='change({s:19})'>修改年龄</button>" +
                        " </div>"
                }
            });
        </script>
    </head>
    <body ng-app="myapp">
        <div class="container" ng-controller="MyController">
            <div>
                我的名字是:<span ng-bind="name"></span>
                <br/>
                <input type="text" ng-model="name" />
                <br/>
                我的age是:<span ng-bind="age"></span>
                <br/>
                <input type="text" ng-model="age" />
            </div>
            <div my-directive my-name="{{name}}" age="age" change="changeAge(s)"></div>
        </div>
    </body>
</html>


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值