前言
各位前辈在上小弟拱礼,小弟唤作查查,何为查查,与渣渣者无水矣,意在小弟虽初出茅庐然已成自我,自认非渣渣尔,然则门下自识术业未成当以与人谦逊见贤思齐,遂以铭。余非师出名门,然从业两载有余,闲暇之时拜读金典,已有些许文章,虽略显轻浮,但玉不雕不成器,在下献丑与众位点拨,全当玩耍,不当之处望各位雅正。
(这逼装的怎么样)
背景
现在市场上流传着很多近几年新生的优秀框架,虽然ExtJS发布的时间很早,现在应该算是古董级别的了,在当时也提出了很多超前的思想如:依赖注入,模块化等,现在一代比一代更优秀,但貌似市场上使用的厂子并不是很多,也有人对它的看法还停留在三代的版本上(现在已经到六代了),本人比较热衷社区讨论,但很少有人对ExtJS有最新的认识,一直在找相关方面的文章,但要么是比较陈旧的,要么是手册类的,因而不才整理出这篇拙作与众位把玩。
巨人ExtJS
ExtJS这个框架有些年头了(07年发布),对于一些从业时间有段时间的人来说都从各方面了解过,有人评价说它“功能丰富,无人能出其右”,但缺点也是存在的,太大,学习曲线陡峭,但这些缺点在我认为确实相对的,如JQuery UI等。
在这里称它为“巨人”一点都不为过,
第一,一般的小型项目hold不住这个巨人,因为收费和学习曲线陡峭很多小公司直接就不考虑它。
第二,身躯太庞大,丰富的组件导致它太重,非大中型管理系统很多难将它的特点发挥出来,它在复杂的业务处理中能节省出大量精力,也就是开发速度快,可以说一个中小型子系统,让一个熟练的前端在一到两周就全部能完成,还是不加班的那种。
第三,就是不在乎你用不用,反正老子是给大厂子做的。
有人说过它丑,烦请查阅07年以前的富客户端长什么样,大家的都知道前端框架都会有自定义样式的设定,当然ExtJS1.0也有,不过那时候多数情况下前端是由后端人员来做的,再加上学习曲线陡峭,所以很少去自定义CSS。且自带那几套皮肤,时间长了审美疲劳之后觉得有点丑,现在看来较之落后,不过现在有好几套自带皮肤,同时像HTML5 CSS3等新标准都已经支持,而且在兼容性方面优化的相当不错,几乎可以不用操心。
相比较同时期的JQuery,ExtJS应该说是一个完整的前端框架,而JQuery是一个扩展库,类比Easy UI是在晚于ExtJS之后的13年发布的,在默认的皮肤和样式上它是照搬ExtJS的classic皮肤的样式,相对ExtJS它比较轻,基于JQuery容易扩展,自己写样式也方便,不是那么干涩让人不太容易琢磨。但熟知JavaScript设计模式的人都知道,JQuery很容易没有编码结构可言,而ExtJS可以说已经很接近面向对象这个概念。
之后在13年发布的ExtJS 4以及后续版本,可以使用Sencha cmd可以构建MVC模式的前端项目,以及完整的模块化管理方案。还推出了一个基于ExtJS的sencha touch的移动端框架,不过在后来的版本中好像取消了,现在的ExtJS 5和6版本都可以直接用做移动端开发,也就是默认支持触屏的事件操作,但没深入了解过,后面再补充吧。
ExtJS简单实验
我喜欢ExtJS的一个重要原因就是它的API很方便查阅,大家可以自行去看一下。
官方API:http://docs.sencha.com/extjs/6.0.0/
ExtJS使用的是盒子模型(也叫做容器),最常用的容器有Panel和Container先来一段代码。
Ext.create('Ext.panel.Panel',{
title: 'Hello',
width: 200,
html: 'World!',
renderTo: Ext.getBody()
});
这样便生成了一个容器,同时可以在里面增加子元素(items),如:button,combox或者其他容器。
Ext.create('Ext.panel.Panel',{
title: 'Hello',
width: 200,
height: 300,
items: [{
xtype: 'button',
text:'OK',
handler: function(){
alert('I\'m a Button');
}},{
xtype: 'panel',
html: 'I\'m a child Panel'
}],
enderTo: Ext.getBody()
});
这个是使用另一套皮肤crisp有Touch模式,也就是兼容了,触屏操作。
也可自定义组件来继承ExtJS的组件并扩展它,如:我们现在要做一个字体样式固定且带一个确定和取消按钮的容器。
Ext.define('MyPanel',{
extend: 'Ext.panel.Panel',//该行继承自Panel,即继承Panel的所有属性和法
width: 200,
height: 200,
margin: '20',
bbar: [
{ xtype: 'button', text: '确定' },
{ xtype: 'button', text: '取消' }
],
bodyStyle: {
color: 'red'
},
html: 'I\'m a Panel'
});
new MyPanel({
renderTo: Ext.getBody()
});
这个Ext.define其实是ExtJS中定义类的方法,写法可能不一样,但几乎完全模拟了面向对象的设计模式。如:
Ext.define('My.awesome.Class',{
someProperty:'something',
someMethod:function(s){
alert(s+this.someProperty);
}
...
});
varobj=newMy.awesome.Class();
obj.someMethod('Say ');
ExtJS在某种程度上是提供了富客户端项目结构乱的解决方案,若是有人非要提ReactJS AngularJS等等,如果非要用ExtJS来做门户网站,ReactJS AngularJS之类用来做富客户端。这就好比用菜刀去砍柴,用斧子去切菜一样,虽然不是非不可以,但其中有数不其尽的坑。
ExtJS和Sencha Cmd---前端的MVC设计模式
ExtJS在4版本的时候同时发布了Sencha Cmd这个工具,Sencha Cmd是针对ExtJS设计的项目构建工具,通过命令可以构建MVC模式的项目还是比较方便的,我们以ExtJS5.0为例演示一下。
安装过程有兴趣的自行查阅一下手册,在官方文档里都有,或者其他博客写的都很详细,我就不再累赘了。
项目结构
通过sencha generate app MyApp D:\MyApp这句命令生成项目MyApp
编码目录再app中,可以看到main文件夹中有三个文件分别是
Main.js----视图view
MainController.js----控制器Controller
MainModel.js---- ViewModel
同时也可以在sass目录写*.sass样式,这些会通过sencha app build打包完成
其实在长期的实践中我发现它的MVC模式并不是需要严格的遵守,也可以混着来,不过根据个人习惯我还是喜欢分清一些好。项目生成好后通过sencha app build编译项目,\MyApp\build\temp\production可以看到编译好的项目,之后就可以通过浏览器来查看。这里要说明一下sencha产生的项目必须要一个服务才能打开,我们可以把项目放到一个服务中查看,可以用sencha cmd自带的服务工具。通过sencha web start开启。之后访问http://localhost:1841/即可。这个端口也是可以配置的。
Main.js
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.container.Container',
requires: [ //引入需要的模块
'MyApp.view.main.MainController',
'MyApp.view.main.MainModel'
],
xtype: 'app-main', //自定义xtype名称,可以在其他模块中通过这个type调用这个模块
controller: 'main', //注入main controller
viewModel: {
type: 'main' //注入main viewModel
},
layout: {
type: 'border'
},
items: [{
xtype: 'panel',
bind: {
title: '{name}'
},
region: 'west',
html: 'This area is commonly used for navigation,for example, using a "tree" component.',
width: 250,
split: true,
tbar: [{
text: 'Button',
handler: 'onClickButton'//事件注册会在controller中映射
}]
},{
region: 'center',
xtype: 'tabpanel',
items:[{
title: 'Tab 1',
html: 'Content appropriate for the currentnavigation.'
}]
}]
});
MainController.js
Ext.define('MyApp.view.main.MainController',{
extend: 'Ext.app.ViewController',
requires: [
'Ext.window.MessageBox'
],
alias: 'controller.main', //声明别名叫main的controller
onClickButton: function () {
Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
},
onConfirm: function (choice) {
if (choice === 'yes') {}}
});
MainModel.js
Ext.define('MyApp.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main', //声明叫main的viewmodel
data: {
name: 'MyApp'
}
//TODO - add data, formulas and/or methods to support your view
});
当前是初始化的一个界面,可以根据需求自行更改。至此就简单说了一下ExtJS和Sencha Cmd,后面若是有需要详细教程的,我会再整理一份。
关于Sencha Cmd我也是在工作的时候一点点上手的,虽然鄙人才疏学浅但接受新事务比较快,且自己喜好钻研,就多看了一些,有些自己的看法且与大家说道说道。
首先实际是用过的朋友就会知道在build完成后把所有的文件集中的一个文件里面去(app.js),有时候会达到好几兆,我见过最大的有12M,加载这这个js会很慢,这似乎是ExtJS设计的不合理之处,但其实不然,不知道大家注意到没有,sencha构建项目和编译项目的命令有没有什么特别之处,
sencha generate app MyApp D:\MyApp
sencha app build
它都是以app开始的,也就是sencha是在创建应用而不是web项目,这点我觉得很多人都没注意过,针对这些我特地翻墙出去查了一些资料,没找到实际的例子,估计都是内部系统,不让人看,倒是在有些论坛的个别回答里有只言片语的描述,他们都是用来做exe应用的,加载的都是本地资源也就不存在资源加载缓慢的问题了。而我们的web应用则无法避免资源加载时延过长这个问题,针对这点我特地做个一个模型,且叫它《ExtJS非阻塞加载设计模式》,后面我会做个专题详细说明。
时间仓促不成文章,望众位指正。