minghui007

我们之所以要定义指令,目的是重用指令。假设有这么一个应用场景:在同一个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

分类:

技术点:

相关文章: