第3章AngularJS的过滤器和作用域 本章学习目标 ●掌握模板中各类过滤器的定义和使用方法; ●理解AngularJS中作用域基础和层级的概念; ●掌握作用域在事件中传播的应用方式。 3.1模板中的过滤器 过滤器的主要功能是格式化数据,这里所说的数据,既包括视图模板中的表达式,也包括控制器中的数组或对象。开发人员不仅可以方便地调用AngularJS中提供的过滤器,还可以自定义属于自己的过滤器。下面通过一个个实用的案例,介绍过滤器的强大功能。 3.1.1排序方式过滤 在介绍排序(orderBy)过滤器之前,先来了解一下过滤器的使用格式。在AngularJS中,过滤器有三种调用方式,分别为单个过滤器、多个过滤器和带参数的过滤器。它们分别对应不同的使用格式,下面分别进行介绍。 1. 单个过滤器 单个过滤器常用于视图模板的表达中,它的使用格式非常简单,调用格式如下所示。 {{表达式 | 过滤器名}} 在上述代码中,“{{}}”双大括号为表达式标记,在括号中,“|”为管道符,通过该符号分成前后两部分,前部分为需要被格式化的表达式,后部分为过滤器的名称,示例代码如下。 {{8.88 |currency}} 代码执行后的结果为$8.88,即在表达式前添加了一个“$”符号。在上述代码中,数值8.88为表达式,而currency则为货币过滤器。 2. 多个过滤器 在视图模板的表达式中,除使用单个过滤器之外,还可以同时调用多个过滤器,格式如下。 {{表达式 | 过滤器名1 | 过滤器名2 | ...}} 在上述代码中,多个过滤器名使用管道符“|”隔开,其他内容与单个过滤器的使用相同。 3. 带参数的过滤器 当然,无论是单个过滤器还是多个过滤器,它们都可以在调用时带参数,调用格式如下。 {{表达式 | 过滤器名1 : 参数1 : 参数2 :...}} 在上述代码中,过滤器的参数跟随在过滤器名称的后面,通过“:”来进行识别,多个参数之间使用“:”进行隔开,多个过滤器同样可以带多个参数,各自用“:”分开,示例代码如下。 {{8.8800 | number:1}} 代码执行后的结果为8.9,虽然表达式值中有4位小数,但由于number过滤器中小数位的参数值为1,因此,在显示时只能保留一位。在保留时,按四舍五入的方式进行取舍,最终数值8.8800经过过滤器格式化后变成8.9。 在介绍完过滤器的多个调用格式之后,接下来详细说明排序过滤器的用法。该过滤器的功能是按照指定的一个或多个对象属性名称进行数据过滤。通过排序过滤器,不仅可以获取按照指定属性名称排序后的数据,还能通过过滤器设置数据返回时的记录总数量。 接下来通过一个完整的示例演示排序过滤器使用的过程。 示例31排序(orderBy)方式过滤 (1) 功能说明。 在页面的视图模板中,调用排序过滤器,将显示的数据按score属性值降序进行排列,并且只显示前3条数据记录。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件31.html,加入如代码清单31所示的代码。 代码清单31排序(orderBy)方式过滤 排序(orderBy)方式过滤
(3) 页面效果。 执行的效果如图31所示。 图31排序(orderBy)方式过滤 (4) 代码分析。 在本示例的代码中,当视图中的模板通过ngrepeat指令绑定控制器中的数据时,调用了orderBy过滤器,代码如下所示。 stu in data | orderBy: '-score' | limitTo: 3 在上述代码中,第一个管道符“|”的左侧为控制器中的数组data,右侧为过滤器的名称orderBy,表示排序过滤器,紧接着的“:”冒号右侧为该过滤器调用时的参数,score为排序时指定的属性名称,即按该属性名排序,默认时为升序,在属性名前添加“”符号后,则变为降序。 第二个管道符“|”的右侧为过滤器的名称limitTo,用于设置数据显示时的记录总量,具体的总量值通过“:”冒号后的参数值来指定,本示例为3,表示只显示3条记录。 3.1.2匹配方式过滤 与排序方式不同,匹配(filter)方式是将字符参数与列表中的各个成员属性值相匹配,如果包含该字符的参数值,则显示该条列表记录,匹配时,不区分字符的大小写。匹配的方式有下列几种。 1. 通过filter过滤器直接匹配包含字符参数的数据 这种方式只需要在调用filter过滤器时,添加一个需要匹配的字符参数,调用格式如下。 {{数据 | filter: '匹配字符'}} 在上述调用格式代码中,匹配字符是过滤器filter的参数,一旦添加该参数,将在整个数据的属性中查找匹配项,找到后则显示,否则不显示,字符内容必须加引号,如下面代码所示。 {{data | filter: '80'}} 上述代码表示,在data数据的各个属性中,查找包含“80”内容的记录。 2. 在字符参数中使用对象形式匹配指定属性的数据 如果在过滤数据时已经明确了数据匹配的属性范围,也可以在字符参数中通过对象的形式指定匹配的属性名称,调用格式如下。 {{数据 | filter: 对象}} 在上述调用格式的对象中,过滤器参数是一个对象,通过key/value方式声明属性名称和匹配的字符内容。如果属性名称为“$”,则表示全部属性中查找,代码如下。 {{data | filter: {score: 80}}} 和 {{data | filter: {$: 80}}} 在上述代码中,前者仅是在score属性列中匹配值为80的数据记录; 后者则是在全部属性列中匹配数据记录,相当于下列代码。 {{data | filter: 80}} 3. 在字符参数中使用自定义函数匹配相应数据 在filter过滤器的字符参数中,除使用对象外,还可以直接调用自定义的函数名,处理相对复杂的数据匹配情况,调用格式如下。 {{数据 | filter: 函数名称}} 在上述调用格式中,过滤器的参数为函数名称,即自定义的匹配数据的函数名。 接下来通过一个完整的示例介绍在filter过滤器的形参中,使用自定义函数来匹配数据的过程。 示例32匹配(filter)方式过滤 (1) 功能说明。 在示例31的基础上,调用匹配过滤器,查询score属性值大于85且小于90的数据记录,并将数据显示在视图模板中。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件32.html,加入如代码清单32所示的代码。 代码清单32匹配(filter)方式过滤 匹配(filter)方式过滤
(3) 页面效果。 执行的效果如图32所示。 图32匹配(filter)方式过滤 (4) 代码分析。 在本示例的代码中,为了查找“分数”在85~90分的数据,在控制器代码中,先添加了一个名为findscore的自定义函数,并在添加函数时定义一个名为e的形参,该形参的值为数据源对象; 然后根据这个数据源对象中的score属性值,通过逻辑运算符返回“分数”在85~90分的记录数据。 最后,在本示例中的视图模板中,当通过filter过滤器匹配数据时,直接将findscore函数名作为过滤器的参数,此时,data对象已作为实参自动传递给findscore函数的形参“e”,函数接收后,根据data对象中的score属性值,将“分数”在85~90分的数据显示在视图模板中。完整实现过程见本示例的代码所示。 3.1.3自定义过滤器 除调用AngularJS中自带的过滤器外,还可以自己定义过滤器。定义过滤器的方法很简单,只需要在页面模块中注册一个过滤器的构造方法。该方法将返回一个以输入值为首个参数的函数,在函数体中实现过滤器的功能。 接下来通过一个完整的示例演示自定义过滤器的过程。 示例33自定义过滤器 (1) 功能说明。 在示例31的基础上,调用自定义的过滤器,查询age属性值大于22且小于28的可选性别的数据记录,并将数据显示在视图模板中。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件33.html,加入如代码清单33所示的代码。 代码清单33自定义过滤器 自定义过滤器
(3) 页面效果。 执行的效果如图33所示。 图33自定义过滤器 (4) 代码分析。 在本示例的控制器代码中,为了实现开发需求,先通过页面模块a3_3调用filter()方法创建一个名称为young的自定义过滤器。该过滤器将通过return语句返回一个函数,而在函数体中,通过代码编写,实现对应需求的功能开发,接下来重点分析这个返回的函数。 首先,在这个函数中,定义了两个形参e和type,e参数在调用过滤器时,将会被需要过滤的数据自动注入。关于自动注入的概念,将会在后续的第4章中进行详细介绍; type参数将会在调用过滤器时,通过“:”冒号形式向过滤器传递实参。 其次,在函数体中,由于本示例过滤的数据是一个数组,因此,首先定义一个名为_out的空数组,并将传来的type性别类型参数进行字符转换,保存在变量_sex中; 然后,对自动注入的e数组中的数据进行遍历,在遍历过程中,检测各项元素的“年龄”属性值是否为“22~28”,并且“性别”属性值是否与变量_sex相符。如果这两项条件都满足,则将该项数组元素添加至空数组_out中,其核心代码如下所示。 ...省略部分代码 var _out = []; var _sex = type ? "男" : "女"; for (var i = 0; i < e.length; i++) { if (e[i].age > 22 && e[i].age < 28 && e[i].sex == _sex) _out.push(e[i]); } ...省略部分代码 最后,在函数体结束时,通过调用return语句,将包含符合过滤条件数据的数组_out返回给自定义过滤器young,当在视图模板中调用过滤器young时,将执行返回函数体中代码,并返回符合条件的数据,最终实现根据需求过滤数据的功能。 3.2过滤器的应用 在3.1节介绍完过滤器在视图模板中的基本用法后,考虑到它在AngularJS中格式化数据的重要性,在本节中再分别介绍两个使用过滤器功能的应用——表头排序和字符查找,进一步巩固3.1节中所学的过滤器基础知识,掌握过滤器在应用开发中的运用方法。 3.2.1表头排序 表头排序是指在使用列表方式显示数据时,如果用户单击列表中某列的表头元素,那么,列表中的全部数据将会自动按该列的属性值自动排序,默认为升序排列,再次单击该列表头元素时,则又变为降序排序。通过这种方式显示数据,可以快速定位所关注列中某项数据,给用户查找数据带来方便。 接下来将使用AngularJS中的过滤器,通过少量简洁的代码,实现表头排序的功能。 示例34表头排序 (1) 功能说明。 在以列表方式显示数据的页面中,当用户单击某项列表头元素时,列表中的数据将会自动根据该项列表的属性值按升序排列,再次单击时,将自动按降序排列。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件34.html,加入如代码清单34所示的代码。 代码清单34表头排序 表头排序
(3) 页面效果。 执行的效果如图34所示。 图34表头排序 (4) 代码分析。 在本示例的代码中,为了实现单击表头排序的功能,首先,向页面控制器代码中添加title和desc两个属性,分别用于绑定排序时的属性名称和排序方向,并赋予初始值name和0,表示数据初始化时按“姓名”属性的升序排列,实现代码如下。 ...省略部分代码 $scope.title = 'name'; $scope.desc = 0; ...省略部分代码 然后,在页面的视图模板中,当通过ngrepeat指令复制并显示数据时,调用了orderBy过滤器,并带有两个参数,第一个“:”冒号后的参数指定排序的属性名,第二个“:”冒号后的参数指定排序时的方向,该参数默认或省略时为升序,1为降序,0为升序。由于title和desc属性的初始值分别为name和0,因此,在页面初始化数据时,将按“姓名”属性的升序排列。 最后,在各个表头元素的单击(ngclick)事件中,分别对title和desc属性值进行重置。由于这两个值与orderBy过滤器的两个参数绑定,因此,当这两个值发生变化时,会自动改变数据显示时的排序属性名称和方向,最终实现按单击表头的属性排序功能。 3.2.2字符查找 在介绍完运用orderBy过滤器实现表头排序功能之后,再来介绍调用filter过滤器实现字符查找的功能。在实现过程中,将调用AngularJS中的filter过滤器,查找与过滤器“:”冒号后字符参数相匹配的数据。如果匹配则显示对应记录,否则不显示任何数据。 接下来通过一个完整的示例介绍调用filte过滤器实现字符查找功能的过程。 示例35字符查找 (1) 功能说明。 在页面的文本框中输入任意字符内容后,将根据输入的内容,在列表的“姓名”属性值中查找相匹配的数据,并将匹配的数据记录显示在页面的列表中。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件35.html,加入如代码清单35所示的代码。 代码清单35字符查找 字符查找
div
(3) 页面效果。 执行的效果如图35所示。 图35字符查找 (4) 代码分析。 在本示例的代码中,为了实现列表中的数据能根据文本框中输入的字符内容自动进行过滤的功能,首先,在页面的控制器代码中添加一个名为key的属性,用于保存用户在文本框中输入的字符内容,该属性初始化时为空值。 然后,通过ngrepeat指令显示数据时,调用AngularJS中的filter过滤器,并添加一个对象性字符参数,指定在数据对象的name属性中查找key值,即在“姓名”属性中查找文本框中输入的字符内容。如果找到,则显示在列表中,否则不显示任何数据。 最后,在页面的视图模板中,通过ngmodel指令双向绑定控制器中的key属性,由于是双向绑定,因此,当用户在文本框中输入任意字符时,属性key的值将自动同步更新。由于该属性值又绑定了filter过滤器的参数,因此,列表中显示的数据也将自动更新,从而最终实现根据用户输入的内容,在列表的“姓名”属性值中查找并显示数据的功能。 3.3作用域概述 在之前的章节中曾经介绍过$scope对象,确切来说,它的实质是一个作用域对象。从对这个对象的使用过程中,发现作用域能存储数据模型、为表达式提供上下文环境和监听表达式的变化并且传播事件,它是页面视图与控制器之间的重要桥梁,也是掌握AngularJS必须知道的基础概念。接下来详细介绍作用域的基础功能及其在DOM中的使用过程。 3.3.1作用域的特点 具体来说,作用域包括下列三个比较显著的特点。  它提供了一个$watch()方法来监听数据模型的变化。之所以能使用ngmodel指令实现数据的双向绑定,就是因为通过调用该方法进行数据模型的监听,只要有一端发生变化,另外绑定的一端将会自动进行数据同步。  它提供另外一个$apply()方法,为各种类型的数据模型改变提供支撑。将它们引入到AngularJS可控制的范围中,最典型的就是控制器。例如,通过页面视图模板中的ngclick指令,执行控制器中的代码。  它为表达式提供了执行的环境。一个表达式必须在拥有该表达式属性的作用域中执行才更加合适。作用域通过提供$scope对象,使所有的表达式都拥有对应的执行环境,也就是执行的上下文对象。 接下来通过一个完整的示例介绍作用域下调用$watch()方法监听数据模块的变化。 示例36$watch()方法的使用 (1) 功能说明。 当在页面的文本框中输入任意“姓名”字符时,另一个div元素中将显示输入框中字符变化的累计次数。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件36.html,加入如代码清单36所示的代码。 代码清单36$watch()方法的使用 $watch()方法的使用
div
div累计变化次数: {{count}} (3) 页面效果。 执行的效果如图36所示。 图36$watch()方法的使用 (4) 代码分析。 在本示例的代码中,当在页面的控制器中编写代码时,先定义两个$scope对象的属性name和count,前者用于使用ngmodel指令绑定文本框中的内容,后者用于记录文本框中字符内容变化的累计次数。 然后,使用作用域中的$watch()方法对$scope中的name属性进行监视,当该属性值发生变化时,将$scope中的count属性值累加1,所以,只要在文本输入框中做任何一次修改,都会通过count属性值反馈至页面中。 之所以可以通过$watch()方法监控模型数据发生的功能,主要是因为在AngularJS的内部,每当对已绑定ngmode指令的name属性进行修改时,其内部的$digest()方法就会自动运行一次,检测已绑定的name属性是否与上一次$digest()方法运行时获取的内容一致。如果不一致,则执行$watch()方法绑定的处理函数,即将count属性值累加1。 3.3.2作为数据模型的作用域 在之前的章节中曾介绍过,作用域是控制器与视图的桥梁,其实,不仅如此,它也是视图和指令的桥梁。因为在自定义指令时,会调用$watch()方法监听各个表达式的变化,一旦作用域中的表达式发生了变化,$watch()方法将通知指令,而指令将根据这个变化重新渲染DOM页面,即更新作用域中的属性值内容。 无论是指令,还是控制器,它们都可以通过作用域与视图中的DOM相绑定,由此,诞生了两个数据关系链,一条是指令——>作用域——>视图,另一条是控制器——>作用域——>视图,且这两条关系链之间还是相互独立的。 接下来再通过一个简单的示例介绍控制器借助作用域控制视图中元素的显示内容。 示例37作为数据模型的作用域 (1) 功能说明。 当在页面的文本框中输入内容时,div元素通过双大括号绑定的方式自动同步该内容,并将它显示在div元素中。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件37.html,加入如代码清单37所示的代码。 代码清单37作为数据模型的作用域 作为数据模型的作用域
div
div{{name}} (3) 页面效果。 执行的效果如图37所示。 图37作为数据模型的作用域 (4) 代码分析。 在本示例的代码中,先通过页面模块定义一个名为c3_7的控制器,在控制器中引用$scope对象注册一个名为name的属性,而$scope对象则通过注册的属性,控制了页面所需的数据模型,视图模板则通过双向绑定的方式传递并显示数据模型中的属性值。 下面分别从控制器和视图这两个角度分析这个示例的具体流程。 从控制器的角度来说,首先,通过$scope对象给name属性赋初始值,然后,通过$watch()方法通知视图中的文本框元素数据已发生了变化,而文本框元素使用ngmodel指令实现了数据的双向绑定,因此,它可以获悉该变化,并将自动同步变化后的name属性值,且将该值渲染至文本框中。 从视图的角度来说,由于文本框通过ngmodel指令进行了数据的双向绑定,因此,首先通过$scope对象获取控制器中name属性值,然后,如果用户在文本框中输入了新的内容,则会自动将该内容传递给控制器中的name属性,保持两端的数据同步。 此外,在div元素中使用双大括号的方式绑定name属性,该方式分为取值和计算两个阶段。在取值时,双大括号中的表达式将会根据$scope对象寻找所属的控制器,并在控制器中找到添加的name属性; 取值后,在控制器中进行计算,并将结果返给$scope对象,视图模板中通过$scope获取最终值并进行渲染,最终显示在页面的div元素中。 3.4作用域的层级和事件 与页面中DOM相类似,作用域在绑定页面元素后,便依据元素的层次关系形成了自身的层级关系,而在这些层级关系中,它们还可以通过事件的传播进行数据的通信,只是这种通过事件的数据通信应用的场景非常有限,仅限于父和子级之间的作用域,接下来逐一进行分析。 3.4.1作用域的层级 与DOM的树状结构类似,作用域也拥有自己的层级,并且与DOM的树状结构相辅相成。它的顶级作用域只有一个,而下面的子级作用域可以创建多个,子级作用域可以继承父级作用域中的全部属性和方法,但同级别子级作用域之间却不可以互相访问各自的属性和方法。 接下来通过一个完整的示例详细介绍作用域的层级关系。 示例38作用域的层级 (1) 功能说明。 以列表的方式分组显示一个学校的两个班级学生信息,两个班级各为一个作用域,而学校则为顶级作用域,两个班级的作用域可以访问顶级作用域中的全部属性。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件38.html,加入如代码清单38所示的代码。 代码清单38作用域的层级 作用域的层级
(3) 页面效果。 执行的效果如图38所示。 图38作用域的层级 (4) 代码分析。 在本示例代码的控制器中,分别定义了三个控制器函数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作用域事件的传播 通过3.4.1节的介绍可知,在AngularJS中,作用域间有非常清晰的层次结构关系,类似于DOM的树状图形,最顶层的就是rootscope作用域,其余的都是在它基础之上进行分支和嵌套的。在这样一种关系下的作用域,它们之间的数据通信变得相对复杂,概括而言,有下列两种方式可以实现作用域的通信。 1. 服务 通过在作用域间创建一个单例的服务(service),由该服务处理各个作用域间的数据通信,这种方式在后续章节中介绍服务概念时,将进行详细的介绍。 2. 事件 除使用服务外,还可以通过作用域间的事件(event)进行数据通信。而要使用事件,则必须调用AngularJS中提供的两个方法$broadcasted()和$emitted(),方法$broadcasted()的功能是将事件从父级作用域传播至子级作用域,它的调用格式如下。 $broadcast(eventname, data) 其中,参数eventname为定义的事件名称,data为事件传播过程中携带的数据信息。 方法$ emitted()的功能是将事件从子级作用域传播至父级作用域,它的调用格式如下。 $emitted(eventname, data) 各参数的功能与$broadcasted()相同,在此不再赘述。 除这两个传播事件的方法外,还需要通过调用$on()方法在作用域中监控传播来的事件并获取相应的数据,它的调用格式如下。 $on(eventname, function(event,data){ //接收传播事件的处理代码 }) 在上述调用格式中,eventname为需要监控的传播事件名称,event为事件传播过程中自带的特征,该特征包括几个重要的属性,如表31所示。 表31各种上网接入方式的比较 属性名称功能说明 event.targetScope 返回发起传播事件的作用域名称 event.currentScope 返回正在接收传播事件的作用域名称 event.name传播事件的名称 event.stopPropagation()防止事件进行冒泡操作的函数 event.preventDefault()阻止代码事件的发生 event.defaultPrevented()当执行了preventDefault()方法时,该属性值为true,否则为false 在$on()方法处理传播事件的函数中,另外一个data参数则为事件在传播过程中携带的数据,通过该对象可以在各个监控的作用域中获取传播时的数据,实现数据通信的功能。 虽然通过作用域的事件可以实现数据通信的功能,但是它们的传播范围非常有限,只能是调用$broadcasted()和$emitted()这两个方法,在父级和子级的作用域间进行传播,其他不具有这种关系的作用域将无法监控到传播来的事件。 接下来通过一个完整的示例说明这个特征。 示例39作用域事件的传播 (1) 功能说明。 在页面中添加两个功能按钮,分别执行$broadcasted()和$emitted()方法进行自定义事件的传播,然后在各个作用域中通过$on()方法监控事件传播的状态,并将接收后的数据显示在控制台中。 (2) 实现代码。 在WebStorm开发工具中,新建一个HTML文件39.html,加入如代码清单39所示的代码。 代码清单39作用域事件的传播 作用域事件的传播
(3) 页面效果。 执行的效果如图39所示。 图39作用域事件的传播 (4) 代码分析。 在本示例的JavaScript代码中,定义了多个控制器,并通过ngcontroller指令将它们与页面中的各个作用域绑定,在其中名为c3_9_s的控制器中,添加了两个方法to_parent()和to_child(),分别用于在单击页面中两个按钮时调用。 在to_parent()方法中,直接调用AngularJS中的$emit()方法,向父作用域传播event_1事件和“事件来源于子级”的字符串数据; 在to_child()方法中,则是调用AngularJS中的$broadcast()方法,向子作用域传播event_2事件和“事件来源于父级”的字符串数据; 而在其他的控制器中,则是通过调用$on()方法接收其他作用域传播来的事件和数据,并将数据显示在浏览器控制台中。 虽然除c3_9_s的控制器外都通过$on()方法接收其他作用域传播来的事件和数据,但当用户在页面中单击第一个按钮时,只有父级作用域才接收到子作用域传播来的event_1事件和相应字符串内容,其他作用域都没有接收到,因此,只在浏览器控制台中显示“在父级中监听到”事件来源于子级”的字样,效果如图39所示。 当用户单击页面中的第二个按钮时,也只有子级作用域才接收到了父级作用域传播来的event_2事件和相应字符串内容,其他作用域同样也都没有接收到。通过这个示例清楚地看到,通过作用域中的事件传播数据的功能非常有限,只能调用AngularJS中的$emit()和$broadcast()方法在父级和子级作用域中进行事件数据的传递。这点在代码开发中是需要注意的。 3.5本章小结 本章首先从AngularJS中的一个重要概念——过滤器讲起,以由浅入深的方式,通过若干个简单、实用、完整的精选示例,详细阐述了过滤器在AngularJS中的应用场景和使用方法。此外,还介绍了AngularJS中的另一个重要知识点——作用域,采用基础理论与示例相结合的方式,逐步深入地介绍了在AngularJS中运用作用域开发应用的方法与技巧。通过本章的学习,读者既能巩固前面所学的知识,又可以为接下来的学习打下更多的实践基础。