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

本篇讲解指令的scope属性:

scope属性值可以有三种:

一.scope:false

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

二.scope:true

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

举个栗子:

html:

<!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:

/*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‘})
            });
        }
    }
});

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

→点击元素后

可以看到,输入颜色值,父作用域里的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.当2和3同名时,可以简写,比如:

属性名叫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属性也被改变了.他们是完全同步的.

和@绑定一样.同样有三个颜色,同样2和3同名的时候可以简写.这里就不再赘述了.

需要特别注意的一点是:@绑定是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()"><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(){alert(‘hello‘)}
});
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();
            });
            ele.bind(‘mouseover‘,function(){
                ele.css({‘cursor‘:‘pointer‘})
            });
        }
    }
});

当点击指令元素的时候,执行sayHello()方法.

和上面两种绑定一样.同样有三个颜色,同样2和3同名的时候可以简写.这里就不再赘述了.

需要注意的是,&绑定的时候,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

时间: 2024-11-05 14:40:49

angular学习笔记(三十)-指令(8)-scope的相关文章

angular学习笔记(三十)-指令(5)-link

这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数:scope,iEle,iAttrs,ctrl,linker scope:指令所在的作用域,这个scope和指令定义的scope是一致的.至于指令的scope,会在讲解scope属性的时候详细解释 iEle:指令元素的jqLite封装.(也就是说iEle可以调用angular封装的简版jq的方法和属

angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指令(5)-link文章也提到了link函数的第五个参数linker. 这篇文章就来讲解一下transclude()方法(linker()方法),是怎么使用的,另外,它也是compile函数的第三个参数,用法一样. 下面就通过自己写一个简易的模拟ngRepeat的指令cbRepeat,来了解linke

angular学习笔记(三十)-指令(7)-compile和link(2)

继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的代码: html: <body> <div ng-controller="compileCtrl"> <level-one> <level-two> <level-three> hello,{{name}} </level-

angular学习笔记(三十)-指令(10)-require和controller

本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐directive> <inner‐directive></inner‐directive> </outer‐directive> 这里有两个指令,一个outer-directive指令元素,它里面又有一个inner-directive指令元素. js: app.directiv

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

之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('directive-name',function(){ var obj = { restrict:'string', priority:number, template:'string', templateUrl:'string', replace:bool, transclude:bool or str

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

本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: E 2. 属性: A 3. 样式类: C 4. 注释: M restrict的值可以是上面四个字母的任意一个或多个的组合. 不指定的话默认为A. 二. replace: 布尔值.是否将指令元素替换,可以有两个值: 1.true: 替换整个使用指令的元素 2.false: 不替换整个使用指令的元素,而

angular学习笔记(三十)-指令(9)-一个简单的指令示例

学了前面这么多关于指令的知识,现在就用指令来写一个小组件:expander 这个组件的功能就是点击开展菜单,再点击收起菜单: ↑↓点击展开收起 下面来看它的代码: html: <!DOCTYPE html> <html ng-app="expanderModule"> <head> <title>20.9 指令-expander</title> <meta charset="utf-8"> &l

angular学习笔记(三十)-指令(7)-compile和link(3)

本篇接着上一篇来讲解当指令中带有template(templateUrl)时,compile和link的执行顺序: 把上一个例子的代码再进行一些修改: html: <!DOCTYPE html> <html ng-app="dirAppModule"> <head> <title>20.8.2 指令-link和compile</title> <meta charset="utf-8"> <

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

这篇主要介绍指令中的templateUrl属性: templateUrl属性值是一个url路径,路径指向一个html模板,html模板会填充(或替换)指令内容: 比如上一篇文章里的案例,我们把原来的template属性改用为templateUrl属性: 方法一: html: <!DOCTYPE html> <html ng-app = 'dirAppModule'> <head> <title>20.2 指令(templateUrl)</title&g