本篇讲解指令的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.当和同名时,可以简写,比如:

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

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

需要特别注意的一点是:@绑定是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的实参传入.

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

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

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

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

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

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

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

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

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

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

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

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

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

  6. angular学习笔记(三十)-指令(2)-restrice,replace,template

    本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...

  7. angular学习笔记(三十)-指令(1)-概述

    之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('dir ...

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

    学了前面这么多关于指令的知识,现在就用指令来写一个小组件:expander 这个组件的功能就是点击开展菜单,再点击收起菜单: ↑↓点击展开收起 下面来看它的代码: html: <!DOCTYPE ...

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

    本篇接着上一篇来讲解当指令中带有template(templateUrl)时,compile和link的执行顺序: 把上一个例子的代码再进行一些修改: 1.将level-two指令改成具有templa ...

随机推荐

  1. linux-shell脚本高并发对文本url批量下载

    实践出真知 样例 http://xxxx.file.myqcloud.com/yyy/xxxxx/xxxx.jpg #注意xxx,yyy都是马赛克 需求: 1.url条数130万左右,图片都说16kB ...

  2. Libevent官方代码样例学习(二)

    连接监听器: 接收TCP连接请求 evconnlistener机制用于监听并接受TCP连接请求. 这些方法在event2/listener.h中声明, 在Libevent 2.0.2-alpha之后的 ...

  3. Log4Net的应用教程之保存日志到数据库中

    关于Log4Net的应用,网上有很多教程,但大多数都是拷贝复制,有些按照他的代码来,运行起来发现也出不来效果,但是Log4net的作用实在是非常大的,或者这里说的不对,应该说系统的日志功能是很重要的也 ...

  4. (原)InsightFace及其mxnet代码

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/8525287.html 论文 InsightFace : Additive Angular Margin ...

  5. VMware Workstation 10.0 简中绿色精简版

    VMware Workstation是强大的虚拟机软件,能在一台机器上同时运行二个或更多Windows.DOS.LINUX系统,并进行开发.测试.部署新的应用程序.VMware10.0 延续VMwar ...

  6. [转载]eclipse自动同步插件filesync的使用

    原文地址:eclipse自动同步插件filesync的使用作者:老孙丢了金箍棒    这篇文章和之前我写的<eclipse下自动部署WEB项目>根本目的是一样的,只是达到目的的方式不同. ...

  7. ubuntu 安装 oracle-xe-universal

    安装oracle-xe-universal第一个我们要考虑的就是交换分区是否足够大, 如果你直接安装,可能会出现下面的英文提示: This system does not meet the minim ...

  8. Xshell连接Ubuntu失败问题

    转自:https://www.linuxidc.com/Linux/2017-08/146222.htm Xshell是一个安全终端模拟软件,可以进行远程登录.我使用XShell的主要目的是在Wind ...

  9. jQuery对象复制

    // 浅层复制(只复制顶层的非 object 元素) var newObject = jQuery.extend({}, oldObject); // 深层复制(一层一层往下复制直到最底层) var ...

  10. Java实现List数组的几种替代方案

    在Java中,禁止定义List<Integer>a[],这种List数组结构. 但是还是可以使用其它一些方式来实现列表数组. 一.使用Node把List包裹起来 public class ...