谈谈Ext JS的组件——组件基类:Ext.Component
概述
Ext.Component是所有Ext组件的基类,这在Ext.Component的API中第一句话就提到了。然后第二段说明了它包含的基本功能:隐藏/显示、启用/禁用以及尺寸控制等。除了以上这些基本功能,其实还包含了很多东西。当然,在API中不可能面面俱到,那么,我们应当如何去理解这个组件基类呢?
Ext.Component===DIV
如果将一个Ext.Component渲染到页面,会看到该组件会简单的在页面中添加一个DIV标记,就是这么简单。也就是说,Ext.Component就相当于一个DIV标记。那么接下来的问题,我可以用这个做些什么?如果是单纯的在页面中使用一个DIV标记,我们可以让它来显示内容,也可以用它来与其他DIV标记构建页面布局,总的来说,就是让它做你想做的事情。
既然一个DIV标记可以做那么多事情,那么如何在Ext.Component实现你所想做的呢?
显示内容
要在DIV内显示内容,有两种方式,一是直接把内容添加在DIV内进行显示,一是找到DIV标记,再将内容添加到DIV标记内。如果你是Ext.Component的设计者,你将如何实现这两种方式呢?一般情况下,第一种方式,都会将内容写到一个变量里,然后用字符串组合的方式将DIV标记与内容结合成一个字符串再输出, 而第二种方式基本都是使用DOM操作先获取元素,再使用元素的innerHTML属性将内容写到DIV标记内。
以上是在不使用任何javascript框架时的实现的方式,而对于Ext.Component这样需要实例化后才能使用的类,如何来实现呢?如果对类设计比较熟悉的话,第一种方式的实现肯定是在类实例化时,将内容绑定到属性上,然后在类内组合字符串进行输出,第二种方式的实现基本就是提供一个方法进行操作了。因而,为了能处理这两种方式,Ext.Component就必须提供一个属性来存放初始化时的内容,还要提供一个方法来来处理内容的更新。在Ext.Component内实现这两个功能的就是HTML配置项和update方法。
注意:配置项(Config options)严格意义上来说就是属性,但是在Javascript中,要区分哪些属性是允许初始化的,哪些属性是不允许初始化的,尤其是对于只读属性这样的属性,要区分实在不容易,如果在API中不加区分,就会增加出错的几率,因而在API中特意添加了配置项这一专属名称以示区别。
当然,对于封装了底层DOM操作和提供了模板的框架了来说,不会真的使用那么简单的实现方法来实现这两种操作。因而,不要把我说的就认为是Ext.Component的实现方式。在这里,只要了解它的基本实现思路就行了。探究起来,Ext.Component实现这两种方式是相当复杂的,复杂的地方主要在渲染流程。这个渲染流程是通过Ext.util.Renderable类实现的,它通过混入(mixins)的方式混入到了Ext.Component中。在这个Ext.util.Renderable类中,渲染HTML代码主要是靠模板与Ext.DomHelper来实现的,有兴趣的可自行研究一下,在这里就不深入了。
样式
对于DIV标记来说,不可缺少的一环当然是为它定义样式或样式类,而这个,与内容的思路是一样的,因而也必须提供相应的配置项与方法,于是就有style和cls配置项以及addCls、removeCls和setStyle方法。至于为什么样式类拆分成了两个方法,而样式只有一个方法,具体原因我只知道样式类在Ext JS的组件中经常需要添加或减少,使用两个方法会更方便,其实还有第三个方法replaceCls,但至于样式为什么只有setStyle方法,具体原因暂时没想到。
尺寸
控制DIV标记的尺寸,以控制DIV标记的可视范围也是经常会使用到的,因而,这个功能是必须有的。
滚动条
当DIV标记固定了尺寸后,内容有可能会超出可视区域,这时候,你是希望显示滚动条,让用户滚动查看内容,还是不显示滚动条,直接忽略多余的内容呢?这也是要考虑的。
隐藏/显示
DIV的显示和隐藏,这个也是会经常使用到的,因而也需要实现。
启用/禁用
当使用DIV标记来实现按钮功能的时候,这个就很有用了。
简化样式设置
一个DIV标记可设置的属性很多,如果某些属性需要经常使用到,如何简化这些属性的输入呢?不可能总是使用style配置项吧?解决办法就是直接通过配置项的方式来直接输入,如padding、margin、border与tabIndex等。
id
说到简化样式设置,不得不说一下id。为DIV标记设置一个id,可以便于快速获取DIV元素,以便进行操作。而对于组件来说了,id配置项设置的值除了昨晚元素的id外,还可以作为组件的id使用,因而具有双重作用。但设置太多id,并不是好事,因为这很容易造成id冲突,因而要慎用。另一直可替代的方法是itemId,不过在Ext JS 5和6,有更好的reference可以使用。助于id所涉及的相关组件查询知识,可以另开一篇文章讲述。
浮动的DIV
不少网站都可以看到一些浮动的元素,如浮动的边栏,弹窗窗口等等,对于一个框架来说,这当然不能少,毕竟窗口、框架的信息窗口都需要使用该功能。为了将浮动功能与基本功能区分开来,便于维护,框架将浮动功能都集中到了Ext.util.Floating类,然后通过混入功能将浮动功能混入Ext.Component类。
动画
有动画功能的框架才够炫,必不可少。在Ext.Component是通过混入Ext.util.Animate实现。
事件
对于事件,这个不用多说,怎么可能缺少呢。要注意的是,在框架中,包含了两种事件,一种是浏览器事件,一种是内部事件。
浏览器事件指的是用户与页面交换所产生的事件,这个是通过Ext.dom.ElementEvent实现的,在使用Ext.dom.Element进行DOM操作时候,就可以为元素绑定或解除事件。Ext.Component组件必不可少的功能就是DOM操作,因而可通过Ext.dom.Element来处理浏览器事件。
内部事件是指Ext JS框架内部的产生事件,如存储(Store)加载了数据,它要通知组件去更新显示,而这就需要通过内部事件进行处理。了解清楚这个非常重要,例如,存储已经加载数据了,但是组件并没有更新显示,到底哪里出错了呢?如果了解了内部事件处理流程,这个就很容易跟踪了,例子中的处理流程就是,存储通过读取器(Reader)调用Ajax去服务器加载数据,数据读取后,代理(Proxy)会再将数据转换为符合存储定义格式的数据,当处理完成后,存储发现有新的数据,就会触发存储的Refresh事件,在组件中,当监听到Refresh事件的时候,说明存储已经读取了数据,可以更新显示了。根据这个流程,如果数据已读取,而没有显示,那说明存在的问题包括:数据读取错误、数据转换错误、存储没有触发Refresh事件,组件没有执行更新显示的代码或更新的时候出现错误。通过逐一排查和跟踪分析这几个流程就很容易找到问题所在了。
在Ext.Component中,内部事件是通过混入Ext.util.Observable类实现的。
Ext.Component与模板
在上面提及过,Ext.Component是使用模板与Ext.DomHelper来渲染元素的,也就是说,我不一定要把Ext.Component渲染为默认的DIV标记,那么该如何来实现呢?根据上面的思路,提供一个配置项就行了,如果是使用模板,可以使用tpl配置项,如果使用Ext.DomHelper,则可继续使用html配置项。
既然可以使用模板,那意味着可以渲染数据,那就必须预留数据接口,因而有了配置项data和setData方法。
远程加载
如果内容是需要远程加载后渲染的,哪怎么办?简单,预留接口就行了,这就是loader配置项,它是通过Ext.ComponentLoader对象来实现远程加载的。
我要直接操控组件生成的元素
虽然使用Ext JS,一般不需要直接操控组件生成的元素,但是确实会存在这方面的需求,因为,必须预留这方面的接口。因而,在组件中提供了getEl方法,用来返回组件所生成的元素中的最顶层的元素,有了这个元素,就可以操控元素及其子元素了,不过,要注意的是,getEl方法返回的是Ext.dom.Element对象的实例,而不是HTMLElement对象。
添加其他功能
经过以上一些处理,Ext.Component的功能就已经相当强大了,但可能还有有一些可能没有考虑到的功能,而这就可以通过混入这样的方式将新功能混入到组件中。在Ext.Component中还混入了以下功能:
- Ext.mixin.Inheritable:为组件提供可继承的配置属性和配置方法。
- Ext.util.Positionable:为组件对象提供定位接口。
- Ext.mixin.ComponentDelegation:为组件提供委托事件。
- Ext.mixin.Bindable:为组件提供bind配置项来连接视图模型。
- Ext.util.ElementContainer:为组件提供操控子元素(组件)的功能。
- Ext.state.Stateful:为组件提供状态功能。
- Ext.util.Focusable:为组件提供获取焦点的功能。
- Ext.mixin.Accessible:为组件提供可访问性方面的功能。
- Ext.util.KeyboardInteractive: 为组件提供键盘交互功能。
小结
通过以上的分析,不知道你是否对组件有了更多的了解?总的来说,我就是基于这样一种思路去了解和认识组件的,这种方式的主要好处就是便于记忆组件的常用配置项和方法。尤其是在需要解决一些问题或实现一些没有提供的功能时候,可以大致知道是否能实现,如何去实现。如果大家在这方面有什么看法或意见,请留言给我,多交流是非常有益的。
在实现了组件基类后,组件就划分为容器类组件与非容器类组件两条主线不断派生出不同的组件,在下一文,将讲述容器类组件。
请大家尊重作者的辛勤劳动,未经允许,请不要转载本文,毕竟读者的支持是作者撰写文章的动力。
谈谈Ext JS的组件——组件基类:Ext.Component的更多相关文章
- 《Ext JS模板与组件基本知识框架图----模板》
最近在整理Ext JS的模板和组件,在参考<Ext JS权威指南>,<Ext JS Web应用程序开发指南>,<Ext JS API>等相关书籍后才写下这篇< ...
- WPF组件开发之组件的基类
之前在网上看到很多关于组件开发的资料,但真正可以用到框架内的却很少.今天贴出自己做的组件,并适合大部分框架的代码. 组件开发需要先做出组件的基类,然后由其他的各类组件去继承这个基类,下面是组件基类的代 ...
- 【Unity3D基础教程】给初学者看的Unity教程(二):所有脚本组件的基类 -- MonoBehaviour的前世今生
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 上一次我们讲了GameObject,C ...
- Ext JS添加子组件的误区
经常会有人问我,为什么我的Grid不能岁窗口的变得而自动调整.了解后,发现很多人都习惯在渲染子组件的时候将Gird渲染到容器内的一个div里,而这正是问题的所在. 在Ext JS的布局系统中,能控制到 ...
- Ext JS学习第十五天 Ext基础之 Ext.DomQuery
此文同来记录学习笔记 •Ext.dom.Query 嗯,这个类一看就是到时做什么事儿的,不用我去过多的解释了.这个类一共提供了8个方法供开发人员去使用. •要说最常用的方法,无非就是Ext.query ...
- Ext.js添加子组件
Ext框架提供了很多api,对于不熟悉的人来说,api的释义有时不够明了.最近碰到了添加子组件的需求,特记录下来. 1. 例如,有一个窗体组件: 现在要为其添加一个字段“学校分类”,变成如下所示: 示 ...
- 《Ext JS模板与组件基本框架图----组件》
本节主要从七个方面讲解组件,组件时什么,它的作用,它的构架,以及怎么创建和周期还有常见的配置项,属性方法和事件以及其层级是什么都进行整理,希望对大家有帮助. 组件的基础知识.png 2 Abstrac ...
- lua -- 所有UI组件的基类
-- 组件行为基础 local Behavior = class("Behavior"); function Behavior:ctor(name) self.owner = ni ...
- Ext JS学习第十四天 Ext基础之 Ext.DomHelper
此文用来记录学习笔记 •我们已经学过了Element这个类,无疑是非常强大的,里面提供了丰富的方法供我们使用,但是Ext为了更加的方便我们去操作DOM元素,特提供了DomHelper这个辅助的工具 ...
- Ext.js 中 25种类型的Ext.panel.Tool
通过Ext.panel.Panel的tools配置项来设置Ext.panel.Tool实例. 要注意的一点是,Ext框架提供的Ext.panel.Tool仅包含按钮图标而具体的点击事件处理函数需要我们 ...
随机推荐
- vue之生命周期
vue的生命周期的过程提供了我们执行自定义逻辑的机会,好好理解它的生命周期,对我们很有帮助. 1.vue实例的生命周期(vue2.0) 2.生命周期描述:(参考截图) 3.例子 window.vm = ...
- Go 语言类型转换
类型转换用于将一种数据类型的变量转换为另外一种类型的变量.Go 语言类型转换基本格式如下: type_name(expression) type_name 为类型,expression 为表达式. 实 ...
- PHP 完整表单实例
PHP - 在表单中确保输入值 在用户点击提交按钮后,为确保字段值是否输入正确,我们在HTML的input元素中插添加PHP脚本, 各字段名为: name, email, 和 website. 在评论 ...
- Docker快速配置指南
下面是一个跟 Docker 网络相关的命令列表. 其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效. -b BRIDGE or --bridge=BRIDGE --指定容 ...
- Python教学相关资料
Python教学调查链接 一.专题 1.绘图 如何开始使用Python来画图 Python画图总结 2.科学计算与数据分析 3.可视化 4.网络爬虫 5. 做笔记 Python-Jupyter Not ...
- SQL_CALC_FOUND_ROWS equivalent in PostgreSQL
https://www.postgresql.org/message-id/1185863074.10580.91.camel%40linda.lfix.co.uk On Tue, 2007-07-3 ...
- springMVC源码分析--SimpleControllerHandlerAdapter(三)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- 搭建ejabberd集群
搭建ejabberd集群(金庆的专栏 2016.8)以2台机器搭建一个ejabberd集群.2台机器都是外网一块网卡,内网另一块网卡.新建一个域名,添加2台机器的外网IP.分别用源码安装ejabber ...
- iOS日历中给一个事件添加多个提醒
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) iOS自带的日历应用中,我们最多只能给一个事件设置2个提醒,但 ...
- Socket接收器——Acceptor
Acceptor是JIoEndpoint的内部类,主要的职责就是监听是否有客户端套接字连接并接收socket,再将socket交由任务执行者(Executor)执行.不断从系统底层读取socket,接 ...