【AngularJS】—— 12 独立做用域

前面经过视频学习了解了指令的概念,这里学习一下指令中的做用域的相关内容。javascript

经过独立做用域的不一样绑定,能够实现更具适应性的自定义标签。借由不一样的绑定规则绑定属性,从而定义出符合更多应用场景的标签。html

本篇将会总结下面的内容:java

  1 为什么须要独立做用域app

  2 如何实现独立做用域ide

  3 做用域的数据绑定函数

本文代码中replace错误写为repalce,可能会干扰正常编码,还请注意修改。我这里就先不修改了!学习

  为什么须要独立做用域

  为了便于理解,先看一下下面这个例子:ui

<!doctype html>
<html ng-app="myApp">
    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
    </head>
    <body>

        <div>
            <xingoo></xingoo>
            <xingoo></xingoo>
            <xingoo></xingoo>
        </div>

        <script type="text/javascript">
            var myAppModule = angular.module("myApp",[]); myAppModule.directive("xingoo",function(){ return { restrict:'AE', template:'<div><input type="text" ng-model="username"/>{{username}}</div><br>', repalce:true } }) </script>
    </body>
</html>

  能够看到,在script中,建立了一个指令,该指令实现了一个自定义的标签。编码

  标签<xingoo></xingoo>的做用是 替换成 一个输入框和一个数据显示。spa

  这样就会出现下面的效果:

  分析:

  当咱们本身建立某个指令时,这个指令确定不可能只使用一次,是要重复屡次使用的,有的在一个页面内或者一个控制器内须要使用屡次。

  相似上面的这种场景,在任何一个输入框内改变数据,都会致使其余的标签内的数据一同发生改变,这显然不是咱们想要的。

  这个时候就须要独立做用域了。

 

  如何实现独立做用域

  下面看看独立做用域的效果:

<script type="text/javascript">
            var myAppModule = angular.module("myApp",[]); myAppModule.directive("xingoo",function(){ return { restrict:'AE', scope:{}, template:'<div><input type="text" ng-model="username"/>{{username}}</div><br>', repalce:true } }) </script>

  只须要在定义指令时,添加scope:{}这个属性,就能够使标签拥有本身的做用域。

  仅仅是添加这一行代码而已,就实现了独立做用域。

  在进行输入时,每一个模板内使用本身的数据,不会相互干扰。

 

  做用域数据绑定  

  自定义标签或者进行扩展时,会有这样的需求场景,要在标签中添加一些属性,实现一些复杂功能。

  关于这些属性,独立做用域是如何的作的呢?看看下面的内容吧。

  举个例子:

<xingoo say="name"></xingoo>
<xingoo say="name()"></xingoo>

  假设传入的是上面这种,咱们如何区分它传入的究竟是变量呢?仍是字符串呢?仍是方法呢?

  所以AngularJS有了三种自定义的做用域绑定方式:

  1 基于字符串的绑定:使用@操做符,双引号内的内容当作字符串进行绑定。

  2 基于变量的绑定:使用=操做符,绑定的内容是个变量。

  3 基于方法的绑定:使用&操做符,绑定的内容时个方法。

  首先看一下基于字符串的绑定:

<!doctype html>
<html ng-app="myApp">
    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
    </head>
    <body>

        <div ng-controller="myAppCtrl">
            <xingoo say="test string"></xingoo>
            <xingoo say="{{str2}}"></xingoo>
            <xingoo say="test()"></xingoo>
        </div>

        <script type="text/javascript">
            var myAppModule = angular.module("myApp",[]); myAppModule.controller("myAppCtrl",['$scope',function($scope){ $scope.str1 = "hello"; $scope.str2 = "world"; $scope.str3 = "angular"; }]); myAppModule.directive("xingoo",function(){ return { restrict:'AE', scope:{ say:'@' }, template:"<div>{{say}}</div><br>", repalce:true } }) </script>
    </body>
</html>

  看一下代码,在body中使用了三次自定义的标签,每种标签的内部有一个say的属性,这个属性绑定了一个双引号的字符串。

  在指令的定义中,添加了scope:{say:'@'}这个键值对属性,也就是说,angular会识别say所绑定的东西是一个字符串

  在模板中,使用表达式{{say}}输出say所表示的内容。

  能够看到,双引号内的内容都被当作了字符串。固然{{str2}}表达式会被解析成对应的内容,再当作字符串。

 

  若是绑定的是一个变量呢!

<!doctype html>
<html ng-app="myApp">
    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
    </head>
    <body>

        <div ng-controller="myAppCtrl"> ctrl:<input type="text" ng-model="testname"><br> directive:<xingoo name="testname"></xingoo>
        </div>

        <script type="text/javascript">
            var myAppModule = angular.module("myApp",[]); myAppModule.controller("myAppCtrl",['$scope',function($scope){ $scope.testname="my name is xingoo"; }]); myAppModule.directive("xingoo",function(){ return { restrict:'AE',  scope:{ name:'=' }, template:'<input type="text" ng-model="name">', repalce:true } }) </script>
    </body>
</html>

  在上面的代码中,能够看到

  1 在控制器myAppCtrl对应的div中,定义了一个变量ng-model —— testname。

  2 testname对应的是输入框中输入的值。

  3 而后把这个变量当作一个参数传递给xingoo这个标签的name属性。

  4 在xingoo标签中,又把这个name绑定到模板中的一个输入框内。

  最终两个输入框的内容被链接起来,不管改变哪个输入框内的值,testname与name都会发生改变。

  经过下面这张图能够看出来:

  在指令中经过scope指定say绑定规则是变量的绑定方式。

  最终经过xingoo标签内的属性依赖关系把 testname与name链接在一块儿:

  

  最后是基于方法的绑定:&操做符

  上面展现了基于字符串和变量的绑定方法,下面看看基于方法的绑定:

<!doctype html>
<html ng-app="myApp">
    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
    </head>
    <body>

        <div ng-controller="myAppCtrl">
            <xingoo say="sayHello(name)"></xingoo>
            <xingoo say="sayNo(name)"></xingoo>
            <xingoo say="sayYes(name)"></xingoo>
        </div>

        <script type="text/javascript">
            var myAppModule = angular.module("myApp",[]); myAppModule.controller("myAppCtrl",['$scope',function($scope){ $scope.sayHello = function(name){ console.log("hello !"+ name); }; $scope.sayNo = function(name){ console.log("no !"+ name); }; $scope.sayYes = function(name){ console.log("yes !"+ name); }; }]); myAppModule.directive("xingoo",function(){ return { restrict:'AE', scope:{ say:'&' }, template:'<input type="text" ng-model="username"/><br>'+
                        '<button ng-click="say({name:username})">click</button><br>', repalce:true } }) </script>
    </body>
</html>

  这段代码中scope中的绑定规则变成了&,也就是方法绑定。

  在body中,经过自定义标签传入了三个方法,分别是sayHello(name),sayNo(name),sayYes(name),这三个方法都须要一个name变量。

  在指令的定义中,模板替换成一个输入框,一个按钮:

  输入框:用于输入username,也就是三个方法须要的参数name。

  按钮:点击触发函数——经过绑定规则,绑定到相应的方法。

  

  也就是说

  经过say在scope中的定义,angular知道了say对应的是个方法;

  经过{name:username}的关联,知道了传入的是username。

  从而交给对应的方法执行。

  

  页面效果:

 

  参考

  [1] 大漠穷求,AngularJS实战:http://www.imooc.com/video/3085/0

相关文章
相关标签/搜索