AngularJS之一个元素上绑定多个指令作用域

前言

众所周知,我们在自定义指令时,会指定它的作用域,即scope设置项(默认值为false)。

且,scope设置项,可以有三种值,从而也就代表三种不同的作用域,下面我们再来一起回顾下:


指令之scope


scope: false


默认值,指令不会新建一个作用域,使用父级作用域。


scope: true


指令会创建一个新的子作用域,原型继承于父级作用域。


scope: {…}


指令会新建一个隔离作用域,不会原型继承父作用域。

好了,通过上面,我们很容易知道,在一个元素绑定一个指令,那么仅仅看这个指令的scope,就轻易知道了它的作用域。

但是,假如我们在一个元素上绑定多个指令呢?这个元素的作用域该如何表现呢?

这就是该篇博客核心----一个元素上绑定多个指令,元素的作用域何去何从。

下面,我们就一起来研究下吧。

另,在此之前,为了接下来的研究方便,我们先约定下,将指令scope的不同值,称为false指令,true指令以及isolated指令。

且需要注意的是,多个指令绑定在一个元素上时,只能有且仅有一个指令拥有template哦,不然会报错的。

Demo如下:

<!--
    多个指令绑定在一个元素上时,只能有一个template,不然会报错,如下
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        <div directive-one directive-tow></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    template:‘<div>one</div>‘
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    template: ‘<div>another</div>‘
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码结果为:

多个false指令共存

首先,我们一起研究的是多个false指令共存情况。

什么意思呢?

即,在一个元素上绑定多个指令,且这些指令的scope值都为false,scope:false。

好了,我们写个demo看看。

<!--
    false指令与false指令共存:表现形式为false
        不创建作用域,共享父作用域
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,得下:

结论如下:

多个false指令共存时,表现形式如同单个指令的scope:false一样,即多个false指令共享父级作用域。

多个true指令共存

何为多个true指令共存?

即,在一个元素上绑定多个指令,且这些指令的scope值都为true,scope:true。

好了,我们写个demo看看。

<!--
    true指令与true指令共存:表现形式为true
        创建一个子作用域,大家一起共享
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,得下:

结论如下:

多个true指令共存时,表现形式如同单个指令的scope:true一样,即多个true指令都共享新创建的子作用域,且子作用域继承自父作用域。

多个isolated指令共存

何为多个isolated指令共存?

即,在一个元素上绑定多个指令,且这些指令的scope值都为对象,scope:{…}。

好了,我们一起写个demo看看。

<!--
    isolated指令与isolated指令共存:报错
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {},
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {},
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

运行代码,报错:

结论如下:

多个isolated指令不能共存,否则报错。

false指令与true指令共存

何为false指令与true指令共存呢?

即,在一个元素上绑定多个指令,且这些指令的scope值,要么是false,要么是true。

好了,我们一起写个demo看看。

<!--
    false指令与true指令共存:(表现形式如true)
        将共享新建的scope,即子作用域,并且该scope原型继承自父scope将共享新建的scope,即子作用域,并且该scope原型继承自父scope
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,如下:

结论如下:

false指令与true指令共存时,表现形式如同单个指令的scope:true一样,即这些指令都共享新创建的子作用域,且子作用域继承自父作用域。

false指令与isolated指令共存

何为false指令与true指令共存呢?

即,在一个元素上绑定多个指令,且这些指令的scope值,要么是false,要么是对象{…}。

好了,我们一起写个demo看看。

<!--
    false指令与isolate指令共存:各管各的
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow name="Monkey"></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {
                        name: ‘@‘
                    },
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,如下:

咦,怎么scope指令不一样呢?

通过上面动态操作图,可知指令的作用域是false的。但是,控制器的结果中却显示两个不同的scope。

那么,是不是与template有关呢?

因为,在一个元素上绑定多个指令,只能有一个指令可以设置template。

上述实验中,我们是在scope为false的指令中设置的template,那么我们再来写个demo,紧紧将scope为false的template内容,移到scope为对象的指令中。

如下:

<!--
    false指令与isolate指令共存:各管各的
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow name="Monkey"></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {
                        name: ‘@‘
                    },
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

我靠,果然与template的设置有关呢。

结论如下:

false指令与isolated指令共存时,表现形式与template的设置有关:

  1、如果template设置在false指令中,则表现为false指令

  2、如果template设置在isolated指令中,则表现为isolated指令,即隔离作用域

注意:上述仅限于通过template呈现在页面中时,在编译链接阶段,他们是各管各的,即isolated指令的作用域是isolated,false指令的作用域是false,因为在上面的chrome控制器的截图,也能看见,它们的scope是不一样的。

true指令与isolated指令共存

何为true指令与isolated指令共存呢?

即,在一个元素上绑定多个指令,且这些指令的scope值,要么是true,要么是对象{…}。

好了,我们一起写个demo看看。

<!--
    true指令与isolate指令共存:各管各
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-tow directive-one name="Monkey"></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {
                        name: ‘@‘
                    },
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,如下:

是八是,发现了点什么?怎么两个scope又是不一样的。哈哈哈,看来它们又是与template的绑定有关呢。

如下,我将template移动到isolated指令中。

<!--
    true指令与isolate指令共存:各管各
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-tow directive-one name="Monkey"></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: {
                        name: ‘@‘
                    },
                    template:‘dire:<input type="text" ng-model="name"/>‘,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

So,结论如下:

true指令与isolated指令共存时,表现形式与template的设置有关:

  1、如果template设置在true指令中,则表现为true指令

  2、如果template设置在isolated指令中,则表现为isolated指令,即隔离作用域

注意:上述仅限于通过template呈现在页面中时,在编译链接阶段,他们是各管各的,即isolated指令的作用域是isolated,true指令的作用域是true,因为在上面的chrome控制器的截图,也能看见,它们的scope是不一样的。

false指令、true指令以及isolated指令三者共存

何为三者共存?

即,在一个元素上绑定多个指令,且这些指令的scope值包括了false、true以及{…}。

好了,我们写个demo看看。

<!--
    isolated指令与false指令、true指令共存:表现形式如下:
        1、假设template绑定在false或者true指令上,表现为true
        2、假设template绑定在isolated上,表现为isolated,前提是只有一个isolated,不然多个isolated会报错
-->
<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
        <script src="angular.js"></script>
    </head>
    <body ng-app="myApp">
        pare:<input type="text" ng-model="name"/>
        <div directive-one directive-tow directive-three></div>
        <script>
            var app = angular.module(‘myApp‘, []);
            app.directive(‘directiveOne‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: true,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveTow‘, function(){
                return {
                    restrict: ‘A‘,
                    scope: false,
                    link: function(scope){
                        console.log(scope);
                    }
                };
            });
            app.directive(‘directiveThree‘, function(){
                return {
                     restrict: ‘A‘,
                     scope: {},
                     template:‘dire:<input type="text" ng-model="name"/>‘,
                     link: function(scope){
                         console.log(scope);
                     }
                };
            });
        </script>
    </body>
</html>

代码稍长,请自行打开

执行上述代码,结果如下:

打开chrome控制器,如下:

可以看见false指令和true指令时,它们都共享同一个作用域,而isolated指令单独一个作用域。

且,上述代码中,我们将template绑定到isolated指令中的,故而表现结果为isolated。

假设,我们将template绑定到false指令或者true指令中呢?

答案,就是如同false指令与true指令共存的情况(PS:这里就不demo啦,不信,就自己动手试试)。

另外,还需要注意的是,isolated指令只能为一个,不然会报错哦,我们在 "isolated指令与isolated指令" 中,已经探讨过啦。

So,结论如下:

当false指令、true指令以及isolated指令共存时,表现形式与template的设置有关:

  1、假设template绑定在true或者false指令中,表现如同“false指令与true指令共存”情况;

  2、假设template绑定在isolated指令中,表现为scope:{…}

注意:上述仅限于通过template呈现在页面中时,在编译链接阶段,他们是各管各的,即isolated指令的作用域是isolated,true指令和false指令来那个的作用域为新建子作用域且共享这个新作用域。

外絮--transclude

当指令中设置了transclude:true,ng-transclude中作用域又会是怎么回事呢?

对于transclude,只需记住:利用ng-transclude嵌入的内容的同时,会创建一个属于自己的作用域,即子作用域,且继承自外部作用域,并非指令。

时间: 2024-10-15 09:44:53

AngularJS之一个元素上绑定多个指令作用域的相关文章

jQuery查看dom元素上绑定的事件列表

作为技术狂热分子的职业本能,看到一个技术产品的功能,总会忍不住想知道它是怎么被实现的.比如我每每看到别人网站一个很炫的界面或者很酷的功能,就忍不住打开了浏览器的控制台... 好,不扯远,说说当你想看到网站上某个元素绑定的事件函数的代码时应该怎么做吧. 查看原生绑定的事件函数代码 所谓原生就是通过addEventListener方法绑定到dom元素上.这个好办: 审查绑定事件的元素(对着它右键->审查元素) 在弹出的Elements视图的控制台,右侧点击“Event Listeners”页签 然后

Jquery 获取元素上绑定的事件

jquery1.x  版本 控制台输入  $.cache[$('#clickMe').get(0)[$.expando]].events 输出元素上绑定的事件 jquery1 , jquery2 版本 ( $._data会在jquery2之后的新版本中废除 ) 控制台输入 $._data($('#clickMe').get(0)).events   原文地址:https://www.cnblogs.com/sky-gfan/p/12072031.html

Jquery 在动态元素上绑定事件

弄了很久却没有弄出来,感觉没有错,但是动态元素上的事件根本就不响应,代码如下: <input type="button" id="btnyes" value="确定" /> <div id="divcontent"> </div> <script> $(function () { $("#btnyes").on("click", funct

JavaScript移除绑定在元素上的匿名事件处理函数

前言: 面试的时候有点蒙,结束之后想想自己好像根本就误解了面试官的问题,因为我理解的这个问题本身就没有意义.但是当时已经有一些思路,但是在一个点上被卡住. 结束之后脑子瞬间灵光,想出了当时没有迈出的那一小步.所以不想计较这个问题本身的意义,单纯的想要把这个我理解错了的问题解决,就当是满足自己一个小小的愿望吧. 问题: 用addEventListener()和attachEvent()给一个DOM元素绑定事件处理程序时,如果传入一个匿名函数,那么用相应的removeEventListener()和

Visual Event :快速查看 DOM 上绑定的 JS 事件

http://web.jobbole.com/82503/ Javascript中的事件经常被认为如谜一般不可解.Javascript是一个事件驱动的语言,在这样的前提下前面的看法是很奇怪,但是说到它们的复杂本质和调试难度时,这样的看法又是很正常的.为此,我创建了可视化事件(Visual Event)来查看DOM节点上绑定的事件. 简介 Visual Event是一个开源 Javascript 书签,能提供绑定在DOM元素上的事件调试信息.Visual Event能显示如下信息: 1.哪一个元素

动态生成元素动作绑定,jquery 1.9如何实现

1.7后增加了 live()1.9后被移除了 网上说可以用 on() 代替 可以实际在动态生成元素上绑定动作,没效果,求解绝方法(用低版本的jQuery这种方法,求别说..) 答: 之前有老兄回答过类似这个问题,我把他的写法给你贴一下吧: 你应该使用 on 事件进行绑定,这样新插入的元素就可以触发点击事件了.http://api.jquery.com/on/ $(function(){ $("body").on("click", '.a', function(){

sharepoint 2013 webservice 已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性

在调用webservice返回数据的时候,?出现以下错误: 已超过传入消息(65536)的最大消息大小配额.若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性 这个就需要在调用webservice的解决方案中,在web.config或者app.config中配置一下: <?xml version="1.0" encoding="utf-8" ?> <configuration> <startup&g

jQuery 判断元素上是否绑定了事件

我研究了一下之后发现,jQuery都将事件缓存起来了,其实也是为了防止内存溢出以及页面unload的时候的速度,也包括多函数触发,方便管理等诸多好处,具体可以参考此文. jQuery会在window.unload的时候卸载所有绑定过的事件,释放内存的. OK,言归正传.判断元素上是否绑定过事件用如下语句 jQuery.data(elem,"events")[type] //老版本也能用 $(elem).data("events")[type] //1.2.3以后才能

WCF 已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性。

在做图片查询的时候,报错 已超过传入消息(65536)的最大消息大小配额.若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性. 因为图片保存在数据库里,所以数据量比较大. WCF默认传输值是65536字节(64KB),这也太小了,我直接改成50M(52428800字节),网上说最大是支持2147483647字节,但是maxReceivedMessageSize属性是Long类型的,应该比这个还要大. 注意,只有TCP.IPC和基本的HTTP绑定才支持流操作,