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嵌入的內容的同時,會創建一個屬於自己的作用域,即子作用域,且繼承自外部作用域,並非指令。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM