angular学习笔记(三十)-指令(8)-scope

本篇讲解指令的scope属性:css

scope属性值能够有三种:html

 

一.scope:falsegit

默认值,这种状况下,指令的做用域就是指令元素当前所在的做用域.github

 

二.scope:truejson

建立一个继承了父做用域的子做用域,这样,指令能够访问到父做用域里的值,父做用域的属性值一旦被修改,子做用域里相应的属性值也会被修改,可是子做用域里的属性值修改,不会影响到父做用域里的属性值app

举个栗子:函数

html:spa

<!DOCTYPE html>
<html ng-app="dirAppModule">
<head>
  <title>20.7.4 指令-scope</title>
  <meta charset="utf-8">
  <script src="../angular.js"></script>
  <script type="text/ng-template" id="text.html">
    <div>
      <h3 style="background-color:{{color}}" ng-transclude></h3>
    </div>
  </script>
  <script src="script.js"></script>
</head>
<body>
  <div ng-controller="bgColor">
    <p>父做用域的color值:{{color}}</p>
    <input ng-model="color" placeholder="请输入颜色值"/>
    <br/>
    <cd-hello><span>code_bunny</span></cd-hello>
  </div>
</body>
</html>

js:rest

/*20.7.4 指令 */
var appModule = angular.module('dirAppModule', []);
appModule.controller('bgColor', function ($scope) {
});
appModule.directive('cdHello', function () {
    return {
        restrict: 'EAC',
        templateUrl: 'text.html',
        replace: true,
        transclude: 'element',
        scope: true,
        link: function (scope, ele, attrs, ctrl, trans) {
            ele.bind('click', function () {
                scope.$apply(function () {
                    scope.color = '#C0DCC0'
                })
            });
            ele.bind('mouseover', function () {
                ele.css({'cursor': 'pointer'})
            });
        }
    }
});

建立一个这样的应用:输入颜色值能够改变指令元素的背景色,点击指令元素,重置颜色值为豆沙绿code

→点击元素后

能够看到,输入颜色值,父做用域里的color值改变,指令的scope里的color值也会改变,可是指令的scope里的color值改变,不会影响到父元素的color值.这就是scope为true时指令的做用域.

 

三.scope:{}

scope属性为一个json对象,这种状况下,为指令建立一个独立的做用域.这个做用域和父做用域没有任何关系.

注意,不可以在这个对象中自定义属性和值,好比scope:{name:'code_bunny'},想象中这样定义就是给指令的独立做用域中定义了一个name属性,值为'code_bunny',但这样是不对的!这个json对象中,只能使用三种绑定策略.若是须要给这个独立做用域添加某个属性,应该在在link函数的scope参数下进行添加.

当这个独立的scope须要和父scope进行通讯时,可使用三种绑定策略:

 

(一)@绑定

@绑定能让独立做用域访问到父做用域里绑定的属性值,可是独立做用域下的这个值被修改,不影响到父做用域.相似于scope:true,可是仅仅是绑定的属性,而不是所有的属性.

来个栗子:

html: 

<!DOCTYPE html>
<html ng-app="dirAppModule">
<head>
  <title>20.7(1)指令-scope</title>
  <meta charset="utf-8">
  <script src="../angular.js"></script>
  <script type="text/ng-template" id="text.html">
    <div>
      <h3 style="background-color:{{color}}" ng-transclude></h3>
    </div>
  </script>
  <script src="script.js"></script>
</head>
<body>
  <div ng-controller="bgColor">
    <input ng-model="color" placeholder="请输入颜色值"/>
    <br/>
    <cd-hello col-attr="{{color}}"><span>code_bunny</span></cd-hello>
  </div>
</body>
</html>

js:

/*20.7.1 指令 */
var appModule = angular.module('dirAppModule', []);
appModule.controller('bgColor',function($scope){});
appModule.directive('cdHello',function(){
    return {
        restrict:'EAC',
        templateUrl:'text.html',
        replace:true,
        transclude:'element',
        scope:{
            color:'@colAttr'
        },
        link:function(scope,ele,attrs,ctrl,trans){
            ele.bind('click',function(){
                scope.$apply(function(){
                    scope.color = '#C0DCC0';
                })
            });
            ele.bind('mouseover',function(){
                ele.css({'cursor':'pointer'})
            });
        }
    }
});

→输入pink→点击元素

能够看到,独立做用域绑定父元素的color属性后,父元素的color属性修改,指令里的color属性也被修改了.可是独立做用域下的color属性被修改,不会影响到父元素.

注意在这段代码里,有这3个颜色:

1.color: 这个是父元素里的color属性名

2.col-attr: 这个是指令元素里用于绑定而建立的一个元素的属性名

3.color: 这个color是独立做用域里的一个属性名

以上三个属性名都是能够本身取的,不须要保持一致.绑定的方法直接看代码里的颜色.

为了看得更清楚,我把它单独拎出来写一下:

  父做用域有一个属性叫color: <input ng-model="color" placeholder="请输入颜色值"/>

指令元素建立一个col-attr属性,让它等于"{{color}}" <cd-hello col-attr="{{color}}"><span>code_bunny</span></cd-hello>
指令的scope里进行绑定:
        scope:{
            color:'@colAttr' }
而后在link函数里就可使用scope.color属性了.

有两个须要注意的地方:

1.元素的属性不能使用驼峰命名,由于html不能识别大小写,只能使用'-',在js绑定时@后面改为驼峰命名.

2.当23同名时,能够简写,好比:

   属性名叫mycolor:<cd-hello mycolor="{{color}}"><span>code_bunny</span></cd-hello>

   scope下的属性名也叫mycolor:  scope:{mycolor:'@mycolor'}

   这种状况下能够简写成: scope:{mycolor:'@'}

 

(二)=绑定:

=绑定可以让独立做用域和父做用域之间的某个属性彻底共享,不管是父做用域下这个属性被修改仍是独立做用域下这个属性被修改,另外一个做用域下的这个属性都会同步变化.

来个栗子: 

<!DOCTYPE html>
<html ng-app="dirAppModule">
<head>
  <title>20.7(2)指令-scope</title>
  <meta charset="utf-8">
  <script src="../angular.js"></script>
  <script type="text/ng-template" id="text.html">
    <div>
      <h3 style="color:{{text_color}};background-color:{{color}}" ng-transclude></h3>
    </div>
  </script>
  <script src="script.js"></script>
</head>
<body>
  <div ng-controller="bgColor">
    <input ng-model="color" placeholder="请输入颜色值"/>
    <br/>
    <cd-hello bg-color="color"><span>code_bunny</span></cd-hello>
  </div>
</body>
</html> 

js:

/*20.7.2 指令 */
var appModule = angular.module('dirAppModule', []);
appModule.controller('bgColor',function($scope){});
appModule.directive('cdHello',function(){
    return {
        restrict:'EAC',
        templateUrl:'text.html',
        replace:true,
        transclude:'element',
        scope:{
            color:'=bgColor'
        },
        link:function(scope,ele,attrs,ctrl,trans){
            ele.bind('click',function(){
                scope.$apply(function(){
                    scope.color = '#C0DCC0'
                })
            });
            ele.bind('mouseover',function(){
                ele.css({'cursor':'pointer'})
            });
        }
    }
});

→输入pink→点击元素

能够看到,和@绑定不一样,当我点击元素,改变了独立做用域下的color属性时,父做用域下的color属性也被改变了.他们是彻底同步的.

和@绑定同样.一样有三个颜色,一样23同名的时候能够简写.这里就再也不赘述了.

须要特别注意的一点是:@绑定是col-attr="{{color}}",而=绑定是bg-color="color".一个是"{{color}}",一个是"color".这个千万不能混淆了

 

(三)&绑定:

&绑定使得独立做用域能够访问父做用域里的函数.

来个栗子:

html:

<!DOCTYPE html>
<html ng-app="dirAppModule">
<head>
  <title>20.7(3)指令-scope</title>
  <meta charset="utf-8">
  <script src="../angular.min.js"></script>
  <script type="text/ng-template" id="text.html">
    <div>
      <h3 ng-transclude></h3>
    </div>
  </script>
  <script src="script.js"></script>
</head>
<body>
  <div ng-controller="sayHelloCode">
    <hello sayhello="sayHello(name)"><span>code_bunny</span></hello>
  </div>
</body>
</html>

js:

/*20.7.3 指令 */
var appModule = angular.module('dirAppModule', []);
appModule.controller('sayHelloCode',function($scope){
    $scope.sayHello=function(a){alert('hello,'+a)}
});
appModule.directive('hello',function(){
    return {
        restrict:'EAC',
        replace:true,
        templateUrl:'text.html',
        transclude:'element',
        scope:{
            sayHello:'&sayhello'
        },
        link:function(scope,ele,attrs,ctrl,trans){
            ele.bind('click',function(){
                scope.sayHello({name:'code_bunny'});
            });
            ele.bind('mouseover',function(){
                ele.css({'cursor':'pointer'})
            });
        }
    }
});

当点击指令元素的时候,执行sayHello()方法.这里须要注意参数的传入方法:

sayhello中有一个形参: 

$scope.sayHello=function(a){alert('hello,'+a)}

在html中定义传入的参数名字叫name

<hello sayhello="sayHello(name)"><span>code_bunny</span></hello>

在调用的时候传入一个对象{name:'code_bunny'}:

scope.sayHello({name:'code_bunny'});

这样,就能够把'code_bunny'做为a的实参传入.

和上面两种绑定同样.一样有三个颜色,一样23同名的时候能够简写.这里就再也不赘述了.

须要注意的是,&绑定的时候,sayhello="sayHello()"绑定的方法是须要()的.

 

三种绑定方法就介绍完了,还有很重要的注意点: 

在使用绑定策略的时候,都是经过指令元素的属性来绑定的,须要注意的是,用做绑定的这个属性名千万不要和指令名自己相同,这有可能会形成错误,好比这样:

<color color="{{mycolor}}"><color/>

指令的名字叫color, 用于绑定mycolor属性值的属性名也叫color,这样就不太好.须要避免这种状况的发生.

 

最后,这三种绑定策略是能够用在同一个指令中的.好比下面这个栗子:

html:

<!DOCTYPE html>
<html ng-app="dirAppModule">
<head>
  <title>20.7(5)指令-scope</title>
  <meta charset="utf-8">
  <script src="../angular.js"></script>
  <script type="text/ng-template" id="text.html">
    <div>
      <h3 style="color:{{textColor}};background-color:{{bgColor}}" ng-transclude></h3>
    </div>
  </script>
  <script src="script.js"></script>
</head>
<body>
<div ng-controller="bgColor">
  <input ng-model="bg_color" placeholder="请输入颜色值"/>
  <input ng-model="text_color" placeholder="请输入颜色值"/>
  <br/>
  <cd-hello col-attr="{{bg_color}}" text-color="text_color" say-hello="sayHello()"><span>code_bunny</span></cd-hello>
</div>
</body>
</html>

js:

/*20.7.5 指令 */
var appModule = angular.module('dirAppModule', []);
appModule.controller('bgColor', function ($scope) {
    $scope.sayHello=function(){alert('hello')}
});
appModule.directive('cdHello', function () {
    return {
        restrict: 'EAC',
        templateUrl: 'text.html',
        replace: true,
        transclude: 'element',
        scope: {
            bgColor: '@colAttr',
            textColor: '=textColor',
            sayHello: '&'
        },
        link: function (scope, ele, attrs, ctrl, trans) {
            ele.bind('click', function () {
                scope.$apply(function () {
                    scope.sayHello();
                    scope.color = '#C0DCC0';
                    scope.textColor = '#ccc';
                })
            });
            ele.bind('mouseover', function () {
                ele.css({'cursor': 'pointer'})
            });
        }
    }
});

→输入背景色为pink,文字色为green→点击元素弹出hello后:

背景色使用@绑定,文字色使用=绑定,sayHello函数使用&绑定.因此,一个指令中能够混合使用多个多种绑定策略.

完整代码:https://github.com/OOP-Code-Bunny/angular/tree/master/OREILLY  20.7.1 指令.html - 20.7.5 指令 .html

           https://github.com/OOP-Code-Bunny/angular/blob/master/OREILLY/script.js

相关文章
相关标签/搜索