Ext JS 5的声明式事件监听
在前文《在Ext JS 5使用ViewControllers》中,简单的介绍了Ext JS 5的一项重要改进——声明式事件监听。在本文,将深度探讨如何使用声明式事件监听啦简化应用程序的视图并减少自定义组件的样板代码。
注意:文章假设你使用的是Ext JS 5.0.1或更高版本。
什么是声明式事件监听?
所谓的“声明式事件监听”,就是指定义在类主体中的监听或在实例的配置对象中使用了listeners配置项。以这种方式来声明事件监听不是Ext JS 5的新功能。在Ext JS 4,可以正在类中声明事件监听,不过只适于处理函数或作用域已定义的情况,例如:
- Ext.define('MyApp.view.User', {
- extend: 'Ext.panel.Panel',
- listeners: {
- // 函数必须内联或在之前已被定义:
- collapse: function() {
- // respond to panel collapse here
- }
- },
- //该方法不能被定义为collapse的处理函数:
- onCollapse: function() {
- }
- });
由于所需的处理函数不能使用类中定义的方法,因而声明式监听在Ext JS 4中的使用有限。开发人员通常会通过重写initComponent方法并使用on方法来添加监听:
- Ext.define('MyApp.view.User', {
- extend: 'Ext.panel.Panel',
- initComponent: function() {
- this.callParent();
- this.on({
- collapse: this.onCollapse,
- scope: this
- });
- },
- onCollapse: function() {
- console.log(this); // the panel instance
- }
- });
作用域解析
在Ext JS 5,对listeners配置项做了改进,允许将事件处理指定为字符串来对应方法名。在运行时(触发事件的任何时候),框架会将这些方面解析为实际的函数引用。我们将这一过程称为事件监听作用域解析。
在Ext JS 4,如果明确给出了“作用域”,才能解析字符串处理程序。而在Ext JS 5,在声明“字符串”处理程序而没有明确声明作用域的时候,为默认作用域解析添加了一些特殊规则。
作用域解析有两种结果:组件或视图控制器(ViewController)。无论是哪种结果,都会从组件开始搜索。作用域可能是组件,也可能是视图控制器,如果不是,框架会“爬”到组件的上层直到找到适合的组件或视图控制器。
解析作用域为组件
框架解析作用域的第一种方式是寻找defaultListenerScope配置项为true的组件。对于类中的事件监听声明,搜索会从组件自身开始。
- Ext.define('MyApp.view.user.User', {
- extend: 'Ext.panel.Panel',
- xtype: 'user',
- defaultListenerScope: true,
- listeners: {
- save: 'onUserSave'
- },
- onUserSave: function() {
- console.log('user saved');
- }
- });
监听被定义在了用户视图的类主体,这意味着框架在提升层次之前会先检查用户视图自身的defaultListenerScope。在当前示例,用户视图将defaultListenerScope设置为了true,那当前监听的作用域将会被解析为用户视图。
对于事件监听被声明在实例配置项的情况,将会条过组件自身,框架会从父容器开始搜索,请参考以下代码:
- Ext.define('MyApp.view.main.Main', {
- extend: 'Ext.container.Container',
- defaultListenerScope: true,
- items: [{
- xtype: 'user',
- listeners: {
- remove: 'onUserRemove'
- }
- }],
- onUserRemove: function() {
- console.log('user removed');
- }
- });
对于用户视图的监听是在实例的配置对象中声明的,这意味着框架会跳过用户视图(尽管它定义了defaultListenerScope为true),且会解析为主视图。
解析作用域为视图控制器
在Ext JS 5,引入了新的控制器类型——Ext.app.ViewController。在《在Ext JS 5使用ViewControllers》中详细介绍了视图控制器,因此这里只讨论与视图控制器与事件监听有关的部分。
与Ext.app.Controller可以管理许多视图不同,每一个视图控制器实例只能绑定一个视图实例。视图与视图控制器之间之间一对一的关系允许视图控制器作为视图或视图的条目中事件监听声明的默认作用域。
对于defaultListenerScope,规则同样适用于视图控制器。类层的监听总是会在搜索组件的上层之前先搜索组件自身的视图控制器。
- Ext.define('MyApp.view.user.User', {
- extend: 'Ext.panel.Panel',
- controller: 'user',
- xtype: 'user',
- listeners: {
- save: 'onUserSave'
- }
- });
- Ext.define('MyApp.view.user.UserController', {
- extend: 'Ext.app.ViewController',
- alias: 'controller.user',
- onUserSave: function() {
- console.log('user saved');
- }
- });
上述监听被声明在用户视图的类主体内,由于用户视图有它自己的控制器,框架会解析作用域为UserController。如果用户视图没有自己的控制器,那么作用域会解析到上层。
另一方面,实例层监听会跳过组件并解析为视图控制器上层的父容器,例如:
- Ext.define('MyApp.view.main.Main', {
- extend: 'Ext.container.Container',
- controller: 'main',
- items: [{
- xtype: 'user',
- listeners: {
- remove: 'onUserRemove'
- }
- }]
- });
- Ext.define('MyApp.view.main.MainController', {
- extend: 'Ext.app.ViewController',
- alias: 'controller.main',
- onUserRemove: function() {
- console.log('user removed');
- }
- });
合并listeners配置项
在Ext JS 4,在基类声明的监听会被子类或实例的listeners配置项的声明完全重写。在Ext JS 5,改进了listeners的API,可适当的合并在基类、子类和实例中的事件监听声明。要想了解其中的行为,可查看以下示例:
- Ext.define('BaseClass', {
- extend: 'Ext.Component',
- listeners: {
- foo: function() {
- console.log('foo fired');
- }
- }
- });
- Ext.define('SubClass', {
- extend: 'BaseClass',
- listeners: {
- bar: function() {
- console.log('bar fired');
- }
- }
- });
- var instance = new SubClass({
- listeners: {
- baz: function() {
- console.log('baz fired');
- }
- }
- });
- instance.fireEvent('foo');
- instance.fireEvent('bar');
- instance.fireEvent('baz');
在Ext JS 4,上面示例只会输出“baz”,但在Ext JS 5,listeners配置项会被正确的合并并输出“foo bar baz”。这就允许类在需要的时候才去声明监听而不需要知道超类是否已经有了监听。
小结
我们任务声明式的监听可大大简化应用程序中的事件监听定义。结合视图控制器用于处理应用程序的逻辑和视图模型的双向绑定,还可以尽可能的改进应用程序的开发体验。尝试去让我们知道你的想法。
Ext JS 5的声明式事件监听的更多相关文章
- cocos2d JS touch屏幕点击事件监听 cc.EventListener.TOUCH
var self = this; this.touchListener = cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- Node.js 教程 05 - EventEmitter(事件监听/发射器 )
目录: 前言 Node.js事件驱动介绍 Node.js事件 注册并发射自定义Node.js事件 EventEmitter介绍 EventEmitter常用的API error事件 继承EventEm ...
- [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
-->事件冒泡和捕获-->事件监听-->阻止事件传播 一.事件冒泡和捕获 1.概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的oncl ...
- [No00006A]Js的addEventListener()及attachEvent()区别分析【js中的事件监听】
1.添加时间监听: Chrom中: addEventListener的使用方式: target.addEventListener(type, listener, useCapture); target ...
- js 事件监听 冒泡事件
js 事件监听 冒泡事件 的取消 [自己写框架时,才有可能用到] <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitiona ...
- js 事件监听 兼容浏览器
js 事件监听 兼容浏览器 ie 用 attachEvent w3c(firefox/chrome) 用 addEventListener 删除事件监听 ie 用 detachEven ...
- JS通用事件监听函数
JS通用事件监听函数 版本一 //把它全部封装到一个对象中 var obj={ readyEvent:function (fn){ if(fn==null){ fn=document; } var o ...
- js 事件监听封装
var eventUtil={//添加句柄 //element,节点 //type,事件类型 //handler,函数 addHandler:function(element,type,handler ...
随机推荐
- 用正则表达式获取所有img标签
public static string ReplaceOrAddImageTitle(string content, string title) { Regex reg = new Regex(@& ...
- iOS平台XML解析类库对比和安装说明
在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.KissXML.Tiny ...
- 关于OC队列
GCD中有三种队列类型: The main queue: 与主线程功能相同.实际上,提交至main queue的任务会在主线程中执行.main queue可以调用dispatch_get_main_q ...
- Struts2 OGNL使用详解(转)
OGNL OGNL ( Object Graph Navigation Language ),对象图导航语言.这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性. 在 Struts2 中,O ...
- HTML-day-2-HTML常用标签
一.常用标签 超链接标签 href-----hyperlink reference _blank,是指在新窗口中打开. 作用:①做锚点的标签,<a name=””></a> ② ...
- CUDA 标准编程模式
前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...
- (实用篇)php处理单文件、多文件上传代码分享
php处理 单文件.多文件上传实例代码,供大家参考,具体内容如下 后台处理文件submit_form_process.php <?php /************************** ...
- JavaScript的一些认识
最近看了一下<nodejs开发指南>发现nodejs在某些特定的领域由他自己的长处,适合密集计算但是业务逻辑比较简单的场景,如果做网站还是选择php吧,呵呵,这本书我除了第5章<用n ...
- css selector
文章一: http://www.jb51.net/css/68287.html 去年我学jQuery的时候,曾经做过一点选择器(selector)的笔记,今天是CSS的选择器,以后还有一部分xPath ...
- Codeforces Round #149 (Div. 2)
A. Heads or Tails 枚举. B. Big Segment \(L=min(l_i),\ R=max(R_i)\) 判断是否存在区间\([L,R]\). C. King's Path 单 ...