博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《AngularJS实战》——3.4 作用域的层级和事件
阅读量:6246 次
发布时间:2019-06-22

本文共 3946 字,大约阅读时间需要 13 分钟。

本节书摘来自华章出版社《AngularJS实战》一 书中的第3章,第3.4节,作者:陶国荣,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.4 作用域的层级和事件

与页面中DOM模型相似,作用域在绑定页面元素后,便依据元素的层次关系形成了自身的层级关系,而在这些层级关系中,它们还可以通过事件的传播进行数据的通信,只是这种通过事件的数据通信应用的场景非常有限,仅限于父和子级之间的作用域,接下来我们逐一进行分析。

3.4.1 作用域的层级

与DOM树状结构类似,作用域也拥有自己的层级,并且与DOM的树状结构相辅相成,它的顶级作用域只有一个,而下面的子级作用域可以创建多个,子级作用域可以继承父级作用域中的全部属性和方法,但同级别子级作用域之间却不可以互相访问各自的属性和方法。接下来,我们通过一个完整的示例来详细介绍作用域的层级关系。

示例3-8 作用域的层级
(1)功能描述
以列表的方式分组显示一个学校的两个班级学生信息,两个班级各为一个作用域,而学校则为顶级作用域,两个班级的作用域可以访问顶级作用域中的全部属性。
(2)实现代码
新建一个HTML文件3-8.html,加入如代码清单3-8所示的代码。
代码清单3-8 作用域的层级

    作用域的层级            
  • {
    {s_name}}{
    {c_name}}
  • 序号 姓名 性别 英语 数学
  • {
    {$index+1}}
    {
    {stu.name}}
    {
    {stu.sex}}
    {
    {stu.english}}
    {
    {stu.maths}}
  • {
    {s_name}}{
    {c_name}}
  • 序号 姓名 性别 英语 数学
  • {
    {$index+1}}
    {
    {stu.name}}
    {
    {stu.sex}}
    {
    {stu.english}}
    {
    {stu.maths}}

(3)页面效果

执行HTML文件3-8.html,最终实现的页面效果如图3-8所示。

f435a3e6795db726bfc12af8151670db83bca747

(4)源码分析

在本示例源代码的控制器中,分别定义了3个控制器函数“c3_8_school”“c3_8_class_1”和“c3_8_class_2”,而在页面中通过向元素属性添加“ng-controller”指令来绑定这些函数,根据这些添加指令元素的DOM层次关系,便形成了作用域的层级关系。
在本示例作用域的层次关系中,“c3_8_school”控制器属于父级,其余两个控制器属于子级,隶属于父级,因此,它们可以直接继承父级作用域中通过“$scope”对象添加的属性或方法,即“s_name”“bold”和“school”属性,如果在父作用域中又通过“$rootScope”对象添加了属性或方法,那么子级作用域将首先访问“$scope”对象,然后再访问“$rootScope”对象。
在子级作用域的视图模板中,当页面渲染“s_name”属性值时,首先,它在取值阶段,将在元素本身所属的作用域中寻找是否存在该属性,如果不存在,则继续向上级作用域中查找,如果都没有找到,则直接在顶级的“$rootScope”对象中查找,确定属性的作用域之后,再进入计算值阶段,计算后,直接将获取的值渲染在页面的元素中。
需要说明的是,每个作用域都会自动添加一个类别名为“ng-scope”的CSS样式,因此,可以通过修改该样式,来显示各作用域所控制的范围区域。

3.4.2 作用域事件的传播

通过前面内容的介绍,我们知道,在Angular中,作用域间有非常清晰的层次结构关系,类似于DOM树状图形,最顶层的就是rootscope作用域,其余的都是在它基础之上进行分支和嵌套的。在这种关系下的作用域,它们之间的数据通信变得相对复杂,概括来说,有下列两种方式可以实现作用域的通信。

1.?服务(service)
通过在作用域间创建一个单例的服务,由该服务来处理各个作用域间的数据通信,这种方式在后续章节中介绍服务概念时,将进行详细的介绍。
2.?事件(event)
除使用服务外,还可以通过作用域间的事件进行数据通信,而要使用事件,则必须调用Angular中提供的两个方法$broadcasted和$emitted,方法$broadcasted的功能是将事件从父级作用域传播至子级作用域,它的调用格式如下。

$broadcast(eventname, data)

其中,参数eventname为定义的事件名称,data为事件传播过程中携带的数据信息。

方法$ emitted的功能是将事件从子级作用域传播至父级作用域,它的调用格式如下。

$emitted(eventname, data)

各参数的功能与$broadcasted相同,在此不再赘述。此外,除这两个传播事件的方法外,还需要通过调用$on方法,在作用域中监控传播来的事件并获取相应的数据,它的调用格式如下。

$on(eventname, function(event,data){    // 接收传播事件的处理代码})

在上述调用格式中,eventname为需要监控的传播事件名称,event为事件传播过程中自带的特征,该特征包括下列几个重要的属性,如表3-1所示。

3b5691acc4c20122fd899e8e164e5b5e30a7f2d4

而在$on方法处理传播事件的函数中,另外一个data参数,则为事件在传播过程中携带的数据,通过该对象可以在各个监控的作用域中获取传播时的数据,实现数据通信的功能。

虽然说通过作用域的事件可以实现数据通信的功能,但是它们的传播范围非常有限,只能是调用$broadcasted和$emitted这两个方法,在父和子级的作用域间进行传播,其他不具有这种关系的作用域将无法监控到传播来的事件。接下来,我们通过一个完整的示例来说明这点特征。
示例3-9 作用域事件的传播
(1)功能描述
在页面中添加两个功能按钮,分别执行$broadcasted和$emitted方法,进行自定义事件的传播,然后在各个作用域中通过$on方法监控事件传播的状态,并将接收后的数据显示在控制台中。
(2)实现代码
新建一个HTML文件3-9.html,加入如代码清单3-9所示的代码。
代码清单3-9 作用域事件的传播

    作用域事件的传播            

(3)页面效果

执行HTML文件3-9.html,最终实现的页面效果如图3-9所示。

d077011194c9c448062228dad6dfc82abd52d05b

(4)源码分析

在本示例的JavaScript代码中,定义了多个控制器,并通过ng-controller指令将它们与页面中的各个作用域相绑定,在其中名为“c3_9_s”的控制器中,添加了两个方法to_parent和to_child,分别用于在单击页面中两个按钮时调用。
在to_parent方法中,直接调用Angular中的$emit方法,向父作用域传播“event_1”事件和“事件来源于子级”的字符串数据,而在to_child方法中,则是调用Angular中的$broadcast方法,向子作用域传播“event_2”事件和“事件来源于父级”的字符串数据;在其他的控制器中,则是通过调用$on方法接收其他作用域传播来的事件和数据,并将数据显示在浏览器控制台中。
虽然除“c3_9_s”的控制器外,都通过$on方法接收其他作用域传播来的事件和数据,但当用户在页面中单击第一个按钮时,只有父级作用域才接收到了子作用域传播来的“event_1”事件和相应字符串内容,其他作用域都没有接收到。因此,只在浏览器控制台中显示“在父级中监听到事件来源于子级”的字样,效果如示意图3-9所示。
当用户单击页面中的第二个按钮时,也只有在子级作用域才接收到了父级作用域传播来的“event_2”事件和相应字符串内容,其他作用域同样也都没有接收到,通过这个示例,我们清楚地看到,通过作用域中的事件传播数据的功能非常有限,只能调用Angular中的$emit和$broadcast方法,在父级和子级作用域中进行事件数据的传递,这点在代码开发时需要注意。

转载地址:http://ifmia.baihongyu.com/

你可能感兴趣的文章
JDK基础--ThreadLocal原理分析与使用场景
查看>>
我的友情链接
查看>>
互联网社交产品与流量需求供求分析
查看>>
Salt Syndic配置
查看>>
IDC简报:2012年2月国外最佳虚拟主机提供商Top5
查看>>
oracle em问题汇总
查看>>
037、Xshell基本设置
查看>>
iOS开发教程——介绍Window的旋转
查看>>
滚动条的宽度计算
查看>>
HTML笔记
查看>>
使用类库
查看>>
DES加密+Base64转换
查看>>
我的友情链接
查看>>
不常用sql语法
查看>>
ftp命令
查看>>
Java内存分配全面浅析
查看>>
32、OSPF在帧中继中不同网络类型配置总结
查看>>
git 之CAfile问题
查看>>
EBS exit_form()
查看>>
手动安装Jenkins插件
查看>>