AngularJs自定義指令詳解(3) - scope


我們之所以要定義指令,目的是重用指令。假設有這么一個應用場景:在同一個html里使用了兩次my-directive,第一個my-directive要展示的是Hello World,第二個my-directive要展示的是Hello AngularJs。

為了實現上面的想法,一個做法是創建兩個控制器(因為控制器會創建子作用域,與外界隔離開),分別定義‘World’和‘AngularJs’輸出:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .controller('myController',function($scope){
                    $scope.greeting = 'World';
                })
                .controller('myController2',function($scope){
                    $scope.greeting = 'AngularJs';
                })
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{greeting}}!'

                    };
                });
    </script>
</head>
<body ng-app="app">
<div ng-controller="myController" my-directive></div>
<div ng-controller="myController2" my-directive></div>
</body>
</html>

目的是達到了,但是做法顯得繁瑣,這樣的指令重用不夠簡潔。

最好的做法當然是類似下面的形式:

<div my-directive greeting="World"></div>
<div my-directive greeting="AngularJs"></div>

怎么做到這一點呢?答案就是使用指令的scope參數,隔離指令的作用域:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{greeting}}!',
                        scope:{
                            greeting:'@'
                        }
                    };
                });
    </script>
</head>
<body ng-app="app">
<div my-directive greeting="World"></div>
<div my-directive greeting="AngularJs"></div>
</body>
</html>

如果不希望屬性名還是greeting,想改個別名,可以這樣:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{greeting}}!',
                        scope:{
                            greeting:'@greet'
                        }
                    };
                });
    </script>
</head>
<body ng-app="app">
<div my-directive greet="World"></div>
<div my-directive greet="AngularJs"></div>
</body>
</html>

注意template里還是使用的greeting,如果改為greet,就解析不出來了!

再看下面的代碼:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{myGreet}}! ',
                        scope:{ }
                    };
                })
                .directive('myDirective2',function(){
                    return{
                        template:'Hello {{myGreet}}! '
                    };
                });
    </script>
</head>
<body ng-app="app">
<div ng-init="myGreet='World'"></div>
<div my-directive></div>
<div my-directive2></div>
<div>Hello {{myGreet}}!</div>
</body>
</html>

在瀏覽器中查看:

Hello !
Hello World!
Hello World!
可見,指令里若添加了scope:{},不管給定的是空對象還是什么,都會隔離指令的作用域。
這使得上面例子里的my-directive指令無法解析myGreet,而未隔離作用域的my-directive2指令卻可以解析myGreet

下面簡單說明一下@=&三個符號的意義。

=不同於@,它綁定的是變量引用,例子:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{greeting}}! ',
                        scope:{
                            greeting:'='
                        }
                    };
                });
    </script>
</head>
<body ng-app="app">
<div ng-init="greet='world'" my-directive greeting="greet"></div>
</body>
</html>

輸出:

Hello world!

如果=號改成@,那么輸出的就是“Hello greet!”了。

我就不愛用=,我非要用@,那也可以:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">
        angular.module('app',[])
                .directive('myDirective',function(){
                    return{
                        template:'Hello {{greeting}}! ',
                        scope:{
                            greeting:'@'
                        }
                    };
                });
    </script>
</head>
<body ng-app="app">
<div ng-init="greet='world'" my-directive greeting="{{greet}}"></div>
</body>
</html>

輸出:

Hello world!

來個雙向綁定玩玩:

<input ng-model="greet"/>
<div ng-init="greet='world'" my-directive greeting="greet"></div>

輸出:

符號&表示綁定一個函數:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../lib/angular-1.3.16/angular.min.js"></script>
    <script src=""></script>
    <title></title>
    <script language="JavaScript">

        angular.module('app',[])
                .run(function($rootScope){
                    $rootScope.test = function(){
                        alert('ok');
                    };
                 })
                .directive('myDirective',function(){
                    return{
                        template:'<button ng-click="greeting()">click me!</button>',
                        scope:{
                            greeting:'&'
                        }
                    };
                });
    </script>
</head>
<body ng-app="app">
<div my-directive greeting="test()"></div>
</body>
</html>

注意在template里,函數名必須跟scope里定義的一致,都是greeting

 


免責聲明!

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



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