AngularJS中Directive指令系列 - scope属性的使用
文章是转的,我做下补充。原文地址:https://segmentfault.com/a/1190000002773689
每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope
参数提供了三种选择,分别是:false
,true
,{}
;默认情况下是false
。
scope = false
首先我们来看一下,当scope
参数被设置为false
时有什么情况发生
在这种情况下,在指令模板中可以直接使用父作用域中的变量,函数
首先我们来创建一个指令,代码如下所示:
http://codepen.io/mafeifan/pen/kXORKN?editors=1010
下面我们来详细解释一下上面的代码:
因为我们将scope
的属性设置为false
所以,我们创建的指令继承了父作用域的一切属性和方法,这也使得在指令的模板中我们可以使用这些属性和方法。
注意:此时我们在输入框里改变名字,会发现上面的两个名字都发生了变化,你肯定会说,这肯定是这样啊,数据绑定嘛,好,我们接着往下走。
scope = true
当把scope
属性设置为true
时,这表明我们创建的指令要创建一个新的作用域,这个作用域继承自我们的父作用域。
等等,刚才我们不是说了,当把scope
属性值设置为false
时,不也是继承我们的父作用域吗?表急,我们接着往下看。
修改上面的JS代码,将指令中的:
scope:false
修改为scope:true
然后我们再试着在我们的input
输入框中写一些字符串,会发现,指令中的那个name
发生了变化,但是指令外的那个name
却没有发生变化,这说明了一个问题。
- 当我们将
scope
设置为true
的时候,我们就新创建了一个作用域,只不过这个作用域是继承了我们的父作用域;我觉得可以这样理解,我们新创建的作用域是一个新的作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充我们这个新的作用域。它和父作用域不是同一个作用域。 - 当我们将
scope
设置为false
的时候,我们创建的指令和父作用域(其实是同一个作用域)共享同一个model
模型,所以在指令中修改模型数据,它会反映到父作用域的模型中。
http://codepen.io/mafeifan/pen/WxVgqL?editors=1010
scope = {}
下面我们要进入一个好玩的部分,当我们将scope
的属性设置为{}
时,我们可以做更多的事情。
AngularJS最强的大的地方之一就是它可以构建组建,无论放在哪里都是可以使用的;
这所以可以做到这些,不得不归功于指令的这个属性;当我们将scope
设置为{}
时,意味着我们创建的一个新的与父作用域隔离的新的作用域,这使我们在不知道外部环境的情况下,就可以正常工作,不依赖外部环境。
当然首先我们还是要给出我们的例子,先看代码,我们修改了上述的JS代码和HTML代码
代码:
http://codepen.io/mafeifan/pen/EyraKX?editors=1010
我们使用了隔离的作用域,不代表我们不可以使用父作用域的属性和方法。
- 我们可以通过向
scope
的{}
中传入特殊的前缀标识符(即prefix
),来进行数据的绑定。 - 在创建了隔离的作用域,我们可以通过
@
,&
,=
引用应用指令的元素的属性,如上面的代码那样,我们可以在<div class="my-directive" my-directive my-name="{{name}}" age="age" change-my-age="changeAge()"></div>
这个元素中,利用前缀标识符通过使用属性my-name
,age
,change-my-age
来引用这些属性的值。
下面我们来看看如何使用这些前缀标识符:
@
单项绑定的前缀标识符
使用方法:在元素中使用属性,好比这样<div my-directive my-name="{{name}}"></div>
,注意,属性的名字要用-
将两个单词连接,因为是数据的单项绑定所以要通过使用{{}}
来绑定数据。
=
双向数据绑定前缀标识符
使用方法:在元素中使用属性,好比这样<div my-directive age="age"></div>
,注意,数据的双向绑定要通过=
前缀标识符实现,所以不可以使用{{}}
。
<
单项绑定的前缀标识符,和=使用类似。不同的是改变内部scope不会反映到parent的scope
使用方法:在元素中使用属性,好比这样<my-component my-attr="parentModel">,directive的定义scope: { localModel:'<myAttr' }。代码
&
绑定函数方法的前缀标识符
使用方法:在元素中使用属性,好比这样<div my-directive change-my-age="changeAge()"></div>
,注意,属性的名字要用-
将多个个单词连接。
注意:在新创建指令的作用域对象中,使用属性的名字进行绑定时,要使用驼峰命名标准,比如下面的代码。
scope: {
// `myName` 就是原来元素中的`my-name`属性
name: '@myName',
age: '=',
// `changeMyAge`就是原来元素中的`change-my-age`属性
changeAge: '&changeMyAge'
}
进一步说明,我们的指令是如何利用这些前缀标识符来寻找我们想要的属性或者函数的?
@
当指令编译到模板的name
时,就会到scope
中寻找是否含有name
的键值对,如果存在,就像上面那样,看到@
就知道这是一个单向的数据绑定,然后寻找原来的那个使用指令的元素上(或者是指令元素本身)含有这个值的属性即my-name={{name}}
,然后在父作用域查找{{name}}
的值,得到之后传递给模板中的name
。=
和&
与@
差不多,只不过=
进行的是双向的数据绑定,不论模板还是父作用域上的属性的值发生改变都会使另一个值发生改变,而&
是绑定函数而已。
AngularJS中Directive指令系列 - scope属性的使用的更多相关文章
- AngularJS中Directive指令系列 - bindToController属性的使用
默认false.这个属性用来绑定scope的属性直接赋给controller.可以为true或者和scope相同格式的对象. 此外使用此属性,要设置controller的别名,通常通过"co ...
- AngularJS中Directive指令系列 - 基本用法
参考: https://docs.angularjs.org/api/ng/service/$compile http://www.zouyesheng.com/angular.html Direct ...
- AngularJS中Directive指令系列
近段时间在研究Angular中的directive用法,打算写个系列.以官方文档为主.并参考诸多教程.加上自己的思考. 基本概念及用法 scope属性的使用. &, <, =, @ 符 ...
- angularjs中directive指令与component组件有什么区别?
壹 ❀ 引 我在前面花了两篇博客分别系统化介绍了angularjs中的directive指令与component组件,当然directive也能实现组件这点毋庸置疑.在了解完两者后,即便我们知道co ...
- angularjs学习之六(angularjs中directive指令的一般编程事件绑定 模板使用等)
angular js 中模板的使用.事件绑定以及指令与指令之间的交互 相应教学视频地址(需FQ):v=aG8VD0KvUw4">angularjs教学视频 <!doctype h ...
- AngularJS中的指令全面解析(转载)
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- 浅谈AngularJS中的指令和指令间的相互通信
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- angularJS中directive父子组件的数据交互
angularJS中directive父子组件的数据交互 1. 使用共享 scope 的时候,可以直接从父 scope 中共享属性.使用隔离 scope 的时候,无法从父 scope 中共享属性.在 ...
- angularJS中directive与directive 之间的通信
上一篇讲了directive与controller之间的通信:但是我们directive与directive之间的通信呢? 当我们两个directive嵌套使用的时候怎么保证子directive不会被 ...
随机推荐
- switch的经典引用
#include<stdio.h> int main(void) { int i; do{ printf("按1,流量查询\n"); printf("按2,人 ...
- Fix git 提交代码错误
今天用git clone下代码,修改,push提交,发现以下错误 [root@localhost gocache]# git push origin master error: The request ...
- node的事件模块应用(译)
第一次接触Node.js时,就觉得他只不过是用javascript实现的服务端.但实际上他提供了许多浏览器端不具备的方法,比如EventEmitter类.我们在本文中来学习如何使用EventEmitt ...
- 汇总常用的jQuery操作Table tr td方法
虽然现在DIV+CSS进行页的布局大行其道,但是很多地方使用table还是有很多优势,用table展示数据是比较方便的,下面汇总了jQuery操作Table tr td常用的方法,熟记这些操作技巧,下 ...
- [UE4]Animation Techniques used in Paragon部分翻译及索引
视频地址:https://www.youtube.com/watch?v=1UOY-FMm-xo 主要内容:该视频由Paragon游戏制作者Laurent Delayen(Senior Program ...
- “设计之变”--从iPhone应用到iPad应用
在做APP的iPad版本设计时,我们常常需要考虑:如何在延续iPhone版本设计特色和优点同时,充分利用iPad的特性更好地进行设计.本文从iPad和iPhone的差异性入手,试图总结这一设计过程中需 ...
- CoreData基础
CoreData用于做数据持久化,适合大数据量的存储和查询 CoreData不是数据库 CoreData可以使用数据库 ,XML等方式来存储数据 CoreData使用面向对象的方式操作数据 CoreD ...
- Apache Marmotta 3.1.0-incubating 发布
Apache Marmotta 3.1.0-incubating 发布了,Apache Marmotta 项目的目的是提供 Linked Data Platform 的开源实现,可让组织轻松的使用.扩 ...
- 分享一个漂亮的ASP.NET MVC界面框架
本文分享一个插件化的界面框架,该框架提供了用户.角色.权限管理功能,也提供了插件的管理和插件中心.下图是该界面框架的样式(全部源码和原理介绍下一篇分享,推荐越多,源码放的越早,呵呵). 要使用该界面框 ...
- Hadoop笔记
教程: Elasticsearch.MongoDB和Hadoop比较: http://blog.csdn.net/hong0220/article/details/47631409