• 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>
    代码稍长,请自行打开

    执行上述代码结果为:

    该篇博客原文地址:http://www.cnblogs.com/giggle/p/5746523.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嵌入的内容的同时,会创建一个属于自己的作用域,即子作用域,且继承自外部作用域,并非指令。

  • 相关阅读:
    无法嵌入互操作类型“-----”。请改用适用的接口
    DataGridView 控件用法(可能不是很全面,因为这是自己常常用到的一些小总结):
    实例化新的一个(new)
    用户 'sa' 登录失败。 (Microsoft SQL Server,错误: 18456)
    开始安装 ASP.NET (4.0.30319.18408)。 出现了错误: 0x8007b799 必须具有此计算机的管理员权限才能运行此工具
    Web 应用程序项目 MvcApplication1 已配置为使用 IIS。
    命名空间中的“MvcBuildViews”。 无效
    SQLServer存储过程入门
    golang fmt格式“占位符”
    go语言基本运算符
  • 原文地址:https://www.cnblogs.com/giggle/p/5746523.html
Copyright © 2020-2023  润新知