ext js 4.2实战5.x哪个最稳定

当前访客身份:游客 [
当前位置:
Ext JS 6 早期版本发布,跨浏览器的RIA框架
Ext JS 6 早期版本发布,新增功能如下:合并了 Ext JS 和 Sencha Touch 功能通过 Sencha Cmd 6,新增时尚主题功能 3D 绘图功能增强 默认Ext JS 网格辅助选项为“actionable mode”模式&更多详情。ExtJS
主要用来开发RIA富客户端的AJAX应用,主要用于创建前端用户界面,与后台技术无关的前端ajax框架。因此,可以把ExtJS用在.Net、
Java、Php等各种开发语言开发的应用中。ExtJs最开始基于YUI技术,由开发人员
JackSlocum开发,通过参考JavaSwing等机制来组织可视化组件,无论从UI界面上CSS样式的应用,到数据解析上的异常处理,都可算是一
款不可多得的JavaScript客户端技术的精品。Ext的UI组件模型和开发理念脱胎、成型于Yahoo组件库YUI和Java平台上Swing两者,并为开发者屏蔽了大量跨浏览器方面的处理。相对来说,EXT要比开发者直接针对DOM、W3C对象模型开发UI组件轻松。
ExtJS 的详细介绍:
ExtJS 的下载地址:
想通过手机客户端(支持 Android、iPhone 和 Windows Phone)访问开源中国:
旧一篇: 12个月前
新一篇: 12个月前
相关讨论话题
你也许会喜欢
好像国内好多用extjs做后台的,难道都掏钱了吗?
2楼:zcool321
就跟不掏钱就不能用似的?
3楼:大嘴吃鸡腿
库别这么大就行。。
4楼:苍松 来自
我只看看有什么新功能,当初我用的是2,还不收费
5楼:钛元素
6楼:crazymus
ExtJS有点笨重,但不得不承认,很强大。
7楼:雨翔河
很强大,但是太大了,不忍直视
8楼:lanmingle
09:19 (非会员)
写都知道好与不好,但是一收费,人们都倾向与开源与免费的.比如知道5收费了,我就再也没有看ext了,直接去看jquery的各种插件
extjs做后台的神器!
10楼:javaflex
产品好,就是太大了,赶快实现像dojo一样模块化,实现按需动态加载吧
11楼:带刀的麦兜
在GPL协议下用免费 土鳖
12楼:boyce小布
一直4.2.1 GPL版的路过,5还没摸透,不敢真上,不做产品盈利,自己做管理系统还是free的
13楼:PSP2
5.x 版本还有一堆 bug
14楼:大大大侠啊
非常强大,适合管理信息系统
15楼:小99 来自
学了几天,不习惯,所以就放弃了
16楼:dengk
我说我们公司还在用2, 你信吗
17楼:奋斗哥 来自
以后Sencha Touch个人开发者可能也要付费,ST 2离死不远了
18楼:zabcd117
引用来自“带刀的麦兜”的评论在GPL协议下用免费 土鳖GPL协议,自己做着玩么?还真以为是免费的么
19楼:Black_JackQ
引用来自“带刀的麦兜”的评论在GPL协议下用免费 土鳖引用来自“zabcd117”的评论GPL协议,自己做着玩么?还真以为是免费的么+1
20楼:Jack_Zhu 来自
当初刚学的时候新版出来了,改GPL了,然后,就没有然后了……
与内容无关的评论将被删除,严重者禁用帐号
本周热点资讯
本站最新资讯当前访客身份:游客 [
当前位置:
发布于 日 2时,
获取itunes的最新歌曲mv,demohttp://114.215.192.70/ext5/tunes下载地址,&http://114.215.192.70/download/tunes.tar.gz
代码片段(11)
1.&[图片] 屏幕快照
上午2.58.30.png&&&&
Main.js&~&1KB&&&&
Ext.define('Tunes.view.main.Main', {
extend: 'Ext.panel.Panel',
requires: [
'Ext.view.View',
'Ext.tree.Panel',
'Tunes.view.main.MainController',
'Tunes.view.main.MainModel'
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
title: 'iTunes Video Preview',
type: 'border'
xtype: 'dataview',
region: 'center',
reference: 'tunesView',
autoScroll: true,
itemTpl: [
'&figure&',
'&img src="{image}" /&',
'&figcaption&&b&{title}&/b&&br /&{artist}&/figcaption&',
'&/figure&'
itemCls: 'video',
overItemCls: 'overvideo',
selectedItemCls: 'selectedvideo',
store: '{tunes}'
xtype: 'treepanel',
region: 'west',
reference: 'countriesTree',
width: 250,
useArrows: true,
iconCls: '',
store: '{countries}'
listeners: {
select: 'onCountrySelect'
xtype: 'container',
region: 'east',
width: 425,
cls: 'preview',
'&tpl if="this.isData(values)"&',
'&h1&{title}&/h1&',
'&h2&{artist}&/h2&',
'&video autoplay controls preload="auto"&',
'&source src="{preview}" type="{codex}"&',
'&/video&',
'&/tpl&', {
isData: function(data){
return !Ext.Object.isEmpty(data.preview);
data: '{tunesView.selection}'
MainModel.js&~&628B&&&&
Ext.define('Tunes.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
requires: [
"Tunes.model.Tune",
"Tunes.model.Country"
data: { },
model: 'Tunes.model.Tune',
autoLoad: true
countries: {
type: 'tree',
model: 'Tunes.model.Country',
expanded: true,
children: [
text: 'Argentine',
leaf: true
text: 'Australia',
leaf: true
text: 'China',
leaf: true
sorters: ['text']
MainController.js&~&453B&&&&
Ext.define('Tunes.view.main.MainController', {
extend: 'Ext.app.ViewController',
requires: [],
alias: 'controller.main',
onCountrySelect: function(selModel, record){
var me = this,
country = record.get('id'),
tunesStore = me.getStore('tunes'),
tunesProxy = tunesStore.getProxy();
tunesProxy.setUrl('/'+ country +'/rss/topmusicvideos/limit=100/explicit=true/json');
tunesStore.load();
Tune.js&~&880B&&&&
Ext.define('Tunes.model.Tune', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field',
'Ext.data.reader.Json',
'Ext.data.proxy.JsonP'
{ name: 'id', type: 'auto', mapping: 'id.attributes["im:id"]' },
{ name: 'artist', type: 'auto', mapping: '["im:artist"].label' },
{ name: 'title', type: 'auto', mapping: '["im:name"].label'},
{ name: 'image', type: 'auto', mapping: '["im:image"][2].label'},
{ name: 'preview', type: 'auto', mapping: 'link[1].attributes.href' },
{ name: 'codex', type: 'auto', mapping: 'link[1].attributes.type' }
//type: 'ajax',
//url: '../shared/data/us/tunes.json',
type:'jsonp',
url: '/zh/rss/topmusicvideos/limit=100/json',
type: 'json',
rootProperty: 'feed.entry',
preserveRowData: true
Country.js&~&69B&&&&
Ext.define('Tunes.model.Country', {
extend: 'Ext.data.Model'
Main.js&~&1KB&&&&
Ext.define('Tunes.view.main.Main', {
extend: 'Ext.panel.Panel',
requires: [
'Ext.view.View',
'Ext.tree.Panel',
'Tunes.view.main.MainController',
'Tunes.view.main.MainModel'
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
title: 'iTunes Video Preview',
type: 'border'
xtype: 'dataview',
region: 'center',
reference: 'tunesView',
autoScroll: true,
itemTpl: [
'&figure&',
'&img src="{image}" /&',
'&figcaption&&b&{title}&/b&&br /&{artist}&/figcaption&',
'&/figure&'
itemCls: 'video',
overItemCls: 'overvideo',
selectedItemCls: 'selectedvideo',
store: '{tunes}'
xtype: 'treepanel',
region: 'west',
reference: 'countriesTree',
width: 250,
useArrows: true,
iconCls: '',
store: '{countries}'
listeners: {
select: 'onCountrySelect'
xtype: 'container',
region: 'east',
width: 425,
cls: 'preview',
'&tpl if="this.isData(values)"&',
'&h1&{title}&/h1&',
'&h2&{artist}&/h2&',
'&video autoplay controls preload="auto"&',
'&source src="{preview}" type="{codex}"&',
'&/video&',
'&/tpl&', {
isData: function(data){
return !Ext.Object.isEmpty(data.preview);
data: '{tunesView.selection}'
MainModel.js&~&628B&&&&
Ext.define('Tunes.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
requires: [
"Tunes.model.Tune",
"Tunes.model.Country"
data: { },
model: 'Tunes.model.Tune',
autoLoad: true
countries: {
type: 'tree',
model: 'Tunes.model.Country',
expanded: true,
children: [
text: 'Argentine',
leaf: true
text: 'Australia',
leaf: true
text: 'China',
leaf: true
sorters: ['text']
MainController.js&~&453B&&&&
Ext.define('Tunes.view.main.MainController', {
extend: 'Ext.app.ViewController',
requires: [],
alias: 'controller.main',
onCountrySelect: function(selModel, record){
var me = this,
country = record.get('id'),
tunesStore = me.getStore('tunes'),
tunesProxy = tunesStore.getProxy();
tunesProxy.setUrl('/'+ country +'/rss/topmusicvideos/limit=100/explicit=true/json');
tunesStore.load();
10.&[文件]
Tune.js&~&880B&&&&
Ext.define('Tunes.model.Tune', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field',
'Ext.data.reader.Json',
'Ext.data.proxy.JsonP'
{ name: 'id', type: 'auto', mapping: 'id.attributes["im:id"]' },
{ name: 'artist', type: 'auto', mapping: '["im:artist"].label' },
{ name: 'title', type: 'auto', mapping: '["im:name"].label'},
{ name: 'image', type: 'auto', mapping: '["im:image"][2].label'},
{ name: 'preview', type: 'auto', mapping: 'link[1].attributes.href' },
{ name: 'codex', type: 'auto', mapping: 'link[1].attributes.type' }
//type: 'ajax',
//url: '../shared/data/us/tunes.json',
type:'jsonp',
url: '/zh/rss/topmusicvideos/limit=100/json',
type: 'json',
rootProperty: 'feed.entry',
preserveRowData: true
11.&[文件]
Country.js&~&69B&&&&
Ext.define('Tunes.model.Country', {
extend: 'Ext.data.Model'
开源中国-程序员在线工具:
相关的代码(441)
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
[JavaScript]
开源从代码分享开始
ym80的其它代码投放本站广告请联系:
Sencha相关书籍
ExtJS 5.1 Beta版发布
Posted 周四, 11/27/2014 - 20:08 by
我们很高兴的宣布,ExtJS 5.1 beta发布了。自从ExtJS 5.0.1,我们一直在努力添加一些令人兴奋的和一些在Sencha社区反映强烈的新功能。ExtJS 5.1为网格(Grid)配备了全新的选择模式(电子表格模型),还包括其他新的组件和增强,如三维柱形图和三维条形图,增强的部分包括画图吧、颜色选取器和评分小部件。我们非常欢迎你们你们到我们的论坛参与ExtJS 5.1beta版本的测试,让这些令人兴奋的新功能达到实用性。
Ext JS网格一直是该框架的核心,在Ext JS 5.1,添加了一个全新的选择模型,就是模仿一个电子表格的体验,这也是被成为“电子表格”的原因。使用该模型,用户可以选择单元格范围:
还可以整列、整行或整个数据集。
甚至可以启用行复选框,这时候电子表格额能是你需要的唯一的选择模型。
在使用电子表格选择模型的时候,还可以添加新的剪贴板插件来让网格与运行在浏览器之外的其他应用程序进行交互。用户可以选择一定范围的数据,然后按行啊CTRL+C(或Mac上的Command+C)来将这些单元格复制到系统剪贴板,再切换到一个应用程序,如微软Excel,并粘贴这些数据。
当然,反过来也是可以的。用户可以在外部应用程序复制数据到剪贴板,然后选择目标网格单元格并按下CTRL+V(或Mac的Command+V)进行粘贴。
所有这些功能添加到网格就如以下代码:
requires: [
'Ext.grid.selection.SpreadsheetModel',
'Ext.grid.plugin.Clipboard'
selModel: {
type: 'spreadsheet',
columnSelect: true
// replaces click-to-sort on header
plugins: 'clipboard'
默认情况下,剪贴板插件使用的是系统剪贴板,不过它也可以使用一个内部缓冲区在网格与应用程序之间交换自定义格式的数据。
在Ext JS 5.1,sencha图表包现在提供了一个"bar3d"系列和要给“numeric3d”轴,将他们结合起来就可以创建一些漂亮的图表,如下面这样的堆积柱形图:
通过提供自定义的renderer方法,还可以简单的调整列的fillStyle,并仍然能获得所有适当的梯度来保持3D外观:
不要漏下这样的条形图:
堆积条形图有两个新的配置项来支持附加的3D功能:fullStack和fullStackTotal。这些配置项允许图表在存储(store)中获取任何数据并去指示系列动态的调整数据的显示以适应指定的范围(通常是0%到100%)。
为了启用完全堆叠,只需要在系列中设置fullStack为true。默认情况下,系列的所有y字段会被堆叠为100这个总数来呈现百分比。不过,可以使用fullStackTotal来将轴调整到任何范围。
最后,使用图表,现在还可以通过添加新的“chartitemevents”插件来将图表连接到item级事件,如itemtap或itemmousemove。
你可能还记得上一篇文章中介绍的颜色选取器组件:
现在,实际上有三个颜色选取器组件。上面的示例显示的是colorfield和colorselector。colorfield组件是表单字段,用来显示颜色值和样本色板。colorselector会在弹出窗口显示。
第三个颜色选取器是colorbutton,即单击颜色色板来显示colorselector。
这些组件都是Ext.ux命名空间的一部分,现在包含在框架的“ext-ux”包中。下面会有“ext-ux”包的更多相关信息。
新的评分小部件(之前的文章提及过)现在也是“ext-ux”包的一部分:
评分小部件类似滑块,允许用户快速的在有限的范围内挑选一个值,与滑块不同的是,评分使用的是重复的标示符号(web字体)来表示选择并通过单击调整值。
在框架的之前版本,Ext.ux命名空间被放在examples/ux文件夹下。这对主题来说是一个挑战,因而,在Ext JS 5.1添加了ext-ux包来包含这些组件。随着时间的推移,现有的Ext.ux成员会被迁移到“ext-ux”或者提升为框架本身。
要在Sencha Cmd应用程序中使用ext-ux包,可以简单将它添加到app.json文件:
"requires": [
作为已给标准包,ext-ux生成的输出可用于没有使用Sencha Cmd的应用程序。以下是文件夹build的内容:
Javascript文件“ext-ux.js”和“ext-ux-debug.js”在build文件夹的顶层。基于应用程序的主题,还要从这三个主题文件夹中选择编译好的CSS文件和resources。
在sencha-charts里的Ext.draw包也有一些令人兴奋的用来徽章超级简单图表的新功能。
现在,可以通过添加“spritevents”插件到Ext.draw.Container来处理诸如itemitap或itemmouseover这样的sprite事件。
还添加了新的API来针对复杂的路径进行点的命中测试:pointInPath和pointOnPath。而且,这里还有几个示例来演示这些新API的运作:
还可以相交两条完整的路径并处理他们的交点。在另外一个新的示例中,可以拖动路径周围的图形并突出显示移动后的交点。
相交的简单线条或由多个贝塞尔曲线段组成的复制图形的详细信息都被隐藏起来了,因而不需要担心路径的内容。
正如所知道的,Ext JS 5.x一直工作在一个共享的sencha-core包。在该版本,已经将Ext.app(MVC和MVVM类)移动到核心并完成事件系统。
Ext.app.Profile最初见于Sencha Touch,现在,它包含在sencha-core,并放在Ext.app命名空间中。也就是说,统一的MVC/MVVM功能集现在可以共享代码了。所以,现在Ext JS 5.1应用程序可以访问Ext.app.Profle,逻辑问题是“它如何工作”和“它提供了什么”。
如果之前从未使用过Sencha Touch配置文件,那可以把他看成一个小型应用程序。应用程序需要在他们的配置文件中列出所需的配置。在运行时,框架会窗口这些配置文件的示例,然后依次序迭代这些列表并调用isActive方法。第一个配置的实例会返回true以确认配置已激活(或当前)。
一个典型的使用配置文件(说的是平板电脑或桌面)的做法是用来控制呈现给用户的顶层视图。使用Ext JS 5.1,有一个新的mainView配置项来指定应用程序或配置,该配置项将取代旧版Ext JS应用程序的“autoCreateViewport”配置项。
在Ext.app.Profile之前,Ext JS 5.0应用程序可以使用responsiveConfig(通过一个插件或混入)来在运行时选择或使用Sencha Cmd生成配置来生成特定目的的生成。应用程序配置位于这两个选项之间。
应用程序配置会在加载时被执行,因而可以做一些需要做的事。他们并不局限于诸如responsiveConfig这样的配置设置,因为他们必须包含在生成中,不过,他们会增加应用程序的大小和空间需求,而不会考虑是在什么设备上运行的。然而,使用生成配置,你可以将只基于苹果应用程序商店的iOS生成中移除安卓系统中特定的内容。
在Ext JS 5.0,引入了源自Sencha Touch新的多设备、启用触屏的事件系统。这将支持滚轮和手势失败系统,以及Ext.Element委托事件模型。新的事件系统的入口是Ext.mixin.Observable。然而,原始的Ext JS事件系统是基于Ext.util.Observable的。这两个类的API基本上是一样的,不过他们在一些不太常见的用例中胡有不同。
在Ext JS 5.1的统一事件系统还将提供这两个类(出于兼容性原因),不过,现在他们之间唯一的区别是Ext.mixin.Observable会在构造函数调用initConfig,而Ext.util.Observable会使用旧的 Ext.apply方法将配置对象属性复制到实例。
在完成统一后,就可以优化事件监听和触发,从而减少这些关键领域的开销。为了解决兼容性问题,一定要去查阅升级指南。
Ext JS 5.1继续扩展了Ext JS 5.0.1中对主要辅助功能的支持,尤其是在在处理各种弹出元素(从组合框到各种擦掉)的时候,已经得到了改善。弹出的级联的focus和blur事件的处理也固定了。
在使用许多触屏设备的时候,需要特定的逻辑来有效的管理滚动。为了规范所有设备的特定行为,在Ext JS 5.1添加了Ext.scroll.Scroller。在使用诸如autoScroll、overflowX或overflowY这样的配置项的ih,框架会创建一个该类的实例,不顾,现在更多的是使用新的scrollable配置项来实现控制。
如果熟悉Sencha Touch,可能会认识该配置项。然而,在Ext JS 5.1,它现在是 Scroller的配置对象。为了返回 Scroller,需要调用getScrollable方法。该对象提供了诸如scrollTo或scrollBy这样的常用的API,因而,不再需要担心如何去管理当前设备上的滚动。
如果应用程序中存在以下这样的配置:
autoScroll: true
// or perhaps just horizontal:
overflowX: true
// or maybe just vertical:
overflowY: true
他们可继续工作,不过,在Ext JS 5.1,以下代码作用是一样的且需优先考虑:
scrollable: true
// equivalent to autoScroll: true
scrollable: 'x'
// equivalent to overflowX: true
scrollable: 'y'
// equivalent to overflowY: true
最后,但并非不重要的是,Sencha Cmd 5.1现在也可使用了。该版本侧重于性能,并引入了新的编译器优化。新的优化,被称为“cssPrefix”,支持在同一个页面使用多个版本的Ext JS来优化框架代码。这被称为“sandboxing”,它要求类似如下的代码:
rowCls: Ext.baseCSSPrefix + 'grid-row',
新的优化将以上代码替换为:
rowCls: 'x-grid-row',
这就消除了数百个这种串联在一个正常的应用程序(整个框架超过1000)中的代码。为了使用这种优化,需要在app.json中修改一下代码:
"output": {
"optimize": true
要使用目前可使用的所有优化,可以这样:
"output": {
"optimize": {
"callParent": true,
"cssPrefix": true,
"defines": true
如果使用Sencha Cmd,需要该版本才能使用Ext JS 5.1。一如以往,Sencha Cmd 5.1支持所有从Ext JS 4.1.1a和Sencha Touch 2.1之后的各框架版本。
可以在这里查看示例和在这里下载测试版本。如果要使用Sencha Cmd,就要使用Sencha Cmd 5.1.0 beta。
希望你们能去试用Ext JS 5.1 beta。除了上面提到的新功能,还有无数的臭虫修复和其他的改进。去我们的论坛提交你的评论以便让我们知道你的想法。
作者: Don Griffin
译者: 黄灯桥
关键字: , , ,
本站采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本站内容必须也遵循“署名-非商业用途-保持一致”的创作共用协议.Ext JS 5初探(一)
在上文提到了本地化文件的问题,然后在Ext JS 5的包里找了找,居然还没包含本地化包。我估计目前还不到考虑本地化的时候。在Sencha Touch中,是没有本地化包的,但是要让Ext JS也不包含本地化包,那有点不现实。如果按照目前的模式,要插入本地化包,是个大问题。要加载本地化包,最佳位置应该是在完成Ext JS的初始化后,在加载应用程序之前,但根据目前的模式,一是自己去修改Bootstrap.json文件,一是在加载应用程序后再加载本地化包。如果自己去修改Bootstrap.json文件,有点不太显示,因为要调整加载文件的idx就很头疼了,如果不调整idx,直接在最后加入本地化包,哪就和直接在初始化应用程序化再加载本地化文件没区别了。在应用程序初始化后加载,是否存在问题,这个需要验证才知道,目前不好下结论。或许在后续版本会很好的解决这个问题也不一定,这个问题只有留待正式版的时候再来讨论。
下面来看看app.js,代码如下:
Ext.application({ name: 'TestExt5', extend: 'TestExt5.Application', autoCreateViewport: 'TestExt5.view.main.Main' });
从代码可以看到,这里与4最大的不同就是autoCreateViewport不再是true或false了,而是直接指定类名了。翻了下app\view目录,没有了4种的Viewport.js文件,这是怎么回事?
打开Ext.app.Application的源文件,看了一下,发现多了一个类Ext.container.plugin.Viewport,也就是说,Viewport现在只是一个容器的插件,不再是独立的容器类了。这样也好,可以避免使用上的混乱,再也不用担心在容器或面板内使用Viewport的情况了。 进入app目录,打开applicaiton.js文件,会看到这个是4的时候没区别。 下面打开TestExt5.view.main.Main的类文件,会看到多了以下几个定义:
controller: 'main', viewModel: { type: 'main' },
这就是Ext JS 5新增的视图控制器和视图模型。
下面先来看看视图模型的定义,代码如下:
Ext.define('TestExt5.view.main.MainModel', { extend: 'Ext.app.ViewModel', alias: 'viewmodel.main', data: { name: 'TestExt5' } //TODO - add data, formulas and/or methods to support your view }); 在代码中,只定义了一个数据name,值为TestExt5。这个值有什么用呢?切换回TestExt5.view.main.Main会看到以下代码:
xtype: 'panel', bind: { title: '{name}' }, region: 'west',
从代码可以看到,这里将数据name绑定给了面板的标题(title),也就是面板的标题将会显示TestExt5,正如文章一图中所示的效果。 下面来看看视图控制器的代码:
Ext.define('TestExt5.view.main.MainController', { extend: 'Ext.app.ViewController', requires: [ 'Ext.MessageBox' ], alias: 'controller.main', onClickButton: function () { Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this); }, onConfirm: function (choice) { if (choice === 'yes') { // } } }); 在代码中定义了两个方法,其中onConfirm是onClickButton方法内Ext.Msg.confirm的回调函数。
切换回TestExt5.view.main.Main,可以看到,面板中的按钮绑定了onClickButton方法,也就是说,当单击按钮时,会直接执行视图控制器的onClickButton方法。这样的写法,实在太好,可减少不少代码量。在使用4的MVC结构,最大的烦恼就是要在控制器中定义一堆的引用以及写一堆的选择符为组件绑定事件。现在,只需要将方法写在视图控制器中,直接在视图中绑定方法就行了。这个得赞一下! 在app\controller目录下有Main.js和root.js两个文件,这两个文件都只有简单的定义,没有具体的执行代码。可以预想,在5的开发中,Main.js的主要作用是作为视图之间的数据传递之用。而root.js,根据注释主要作用是用来定义路由。 在文章的最后,我们来生成一下应用程序。打开命令提示符窗口,进入应用程序的目录,在这里是C:\TestExt5,然后运行以下命令:
sencha app build 等编译完成,可在C:\TestExt5\build\production\TestExt5目录看到以下的文件和目录:
打开index.html,会发现有一大段的压缩了的Javascript代码,这段代码仔细看了下,就是把bootstrap.js文件压缩后的代码。不过还是有变化的,就是在压缩代码的第一行会看到以下代码:
Ext.manifest=&app& 也就是说,这次要去加载的不是bootstrap.json文件了,而是app.json文件了,也就是说,这时候是app.json文件发挥作用的时候了,要好好并仔细阅读一下app.json文件里面的注释了,不然贸然去修改该文件,很可能会出错。
好了,有关Ext JS 5的初步探讨就到这了,未来有机会研究一下Ext JS 5的新功能。
17:03&&&[]
Sencha Cmd的Web服务器功能来测试一下生成的应用程序,命令如下:
sencha fs web -port 8000 start -map C:\TestExt5
在浏览器地址栏输入“localhost:8000”,会看到如下图所示的效果。应用程序结构和Ext JS 4时生成的应用程序
22:13&&&[]
在Bootstrap.js文件中,总共有1500行(包含注释和空行),使用编辑器的代码折叠功能就如下图可以一窥全貌了。
从代码可以看到,这里主要定义了Ext.Boot、Ext.globalEval、Ext.Microloader和Ext.manifest这4个对象或属性。关键代码是最后一句的调用Ext.Microloader的load方法,下面来研究一下这个load方法,代码如下:
load: function (manifestDef) { var manifest = Microloader.initManifest(manifestDef), loadOrder = manifest.loadOrder, loadOrderMap = (loadOrder) ? Boot.createLoadOrderMap(loadOrder) : null, urls = [], js = manifest.js || [], css = manifest.css || [], resources = js.concat(css), resource, i, len, include, loadedFn = function () { _loaded = Microloader.notify(); }; for (len = resources.length, i = 0; i & i++) { resource = resources[i]; include = if (resource.platform && !Microloader.filterPlatform(resource.platform)) { include = } if (include) { urls.push(resource.path); } } if (loadOrder) { manifest.loadOrderMap = loadOrderM } Boot.load({ url: urls, loadOrder: loadOrder, loadOrderMap: loadOrderMap, sequential: true, success: loadedFn, failure: loadedFn }); },
代码第一句执行了Microloader的initManifest方法,代码如下:
initManifest: function (manifest) { Microloader.init(); var tmpManifest = manifest || Ext. if (typeof tmpManifest === &string&) { var url = Boot.baseUrl + tmpManifest + &.json&, content = Boot.fetchSync(url); tmpManifest = JSON.parse(content.content); } Ext.manifest = tmpM return tmpM },
根据load方法的调用,可以知道manifest为null,不过这里第一句又先调用了Microloader的init方法,代码如下:
init: function () { Microloader.initPlatformTags(); Ext.filterPlatform = Microloader.filterP },
又要跳到initPlatformTags方法,快给转晕了,代码如下:
initPlatformTags: function () { Microloader.platformTags = Microloader.detectPlatformTags(Microloader.platformTags); },
还跳,这里省去n字,继续去看detectPlatformTags方法,代码如下:
detectPlatformTags: function (tags) { var ua = navigator.userAgent, isMobile = tags.isMobile = /Mobile(\/|\s)/.test(ua), isPhone, isDesktop, isTablet, touchSupported, isIE10, isBlackberry, element = document.createElement('div'), uaTagChecks = [ 'iPhone', 'iPod', 'Android', 'Silk', 'Android 2', 'BlackBerry', 'BB', 'iPad', 'RIM Tablet OS', 'MSIE 10', 'Trident', 'Chrome', 'Tizen', 'Firefox', 'Safari', 'Windows Phone' ], isEventSupported = function(name, tag) { if (tag === undefined) { tag = } var eventName = 'on' + name.toLowerCase(), isSupported = (eventName in element); if (!isSupported) { if (element.setAttribute && element.removeAttribute) { element.setAttribute(eventName, ''); isSupported = typeof element[eventName] === 'function'; if (typeof element[eventName] !== 'undefined') { element[eventName] = } element.removeAttribute(eventName); } } return isS }, uaTags = {}, len = uaTagChecks.length, check, for (c = 0; c & c++) { check = uaTagChecks[c]; uaTags[check] = new RegExp(check).test(ua); } isPhone = (uaTags.iPhone || uaTags.iPod) || (!uaTags.Silk && (uaTags.Android && (uaTags['Android 2'] || isMobile))) || ((uaTags.BlackBerry || uaTags.BB) && uaTags.isMobile) || (uaTags['Windows Phone']); isTablet = (!tags.isPhone) && ( uaTags.iPad || uaTags.Android || uaTags.Silk || uaTags['RIM Tablet OS'] || (uaTags['MSIE 10'] && /; Touch/.test(ua)) ); touchSupported = // if the browser has touch events we can be reasonably sure the device has // a touch screen isEventSupported('touchend') || // browsers that use pointer event have maxTouchPoints & 0 if the // device supports touch input // http://www.w3.org/TR/pointerevents/#widl-Navigator-maxTouchPoints navigator.maxTouchPoints || // IE10 uses a vendor-prefixed maxTouchPoints property navigator.msMaxTouchP isDesktop = !isPhone && !isT isIE10 = uaTags['MSIE 10']; isBlackberry = uaTags.Blackberry || uaTags.BB; apply(tags, Microloader.loadPlatformsParam(), { phone: isPhone, tablet: isTablet, desktop: isDesktop, touch: touchSupported, ios: (uaTags.iPad || uaTags.iPhone || uaTags.iPod), android: uaTags.Android || uaTags.Silk, blackberry: isBlackberry, safari: uaTags.Safari && isBlackberry, chrome: uaTags.Chrome, ie10: isIE10, windows: isIE10 || uaTags.Trident, tizen: uaTags.Tizen, firefox: uaTags.Firefox }); if (Ext.beforeLoad) { tags = Ext.beforeLoad(tags); } },
好了,这次不用再跳了。代码先调用navigator.userAgent返回了浏览器用于 HTTP 请求的用户代理头的值,这个值可用来检查浏览器和版本号。如果值包含了字符串Mobile,说明是移动设备,这时候isMobile为true。在定义了一堆变量后,在页面中添加了一个div元素。接下来的uaTagChecks根据变量名可以知道,这是要检测的标记了。
接下来定义了isEventSupported函数,看名字就知道是用来检测是否支持事件的。根据函数内容,可以看到检测方式有两种,第一种就是检测事件名是否在刚才创建的元素div内,如果在,说明支持。第二种方法就是div元素上添加事件属性,然后判断元素对象内的事件属性是否为function,如果是,说明支持,否则就是不支持了。 定义结束后,就开始使用循环来检测平台属性了,检测结果将保存在uaTags对象中,对象中的属性名称就是uaTagChecks中的字符串,值就是检测值。 检测完之后就要给几个变量赋值了,赋值完成后,会调用apply方法将对象的成员复制到tags中。在调用apply方法时,还调用了loadPlatformsParam方法,该方法我就不列了,它的主要作用就是可通过访问地址的platformTags参数来自定义平台参数,这样做的目的是可以通过浏览器做一些模拟效果,如桌面pc模拟平板的效果。 下一句判断Ext.beforeLoad是否存在,在当前情况是不存在的,所以,这段代码可以忽略。最后是将平台检测结果返回了。
返回initPlatformTags方法,可以知道Microloader.platformTags现在指向的平台检测结果。再返回init方法,在计算出平台检测结果后,会将Ext.filterPlatform属性指向Microloader.filterPlatform方法,也就是说,在调用Ext的filterPlatform方法时,会执行Microloader.的filterPlatform方法,该方法的主要作用就是把不需要的平台过滤掉。 好了,现在返回initManifest方法,在执行完init方法后,会给tmpManifest赋值,由于在当前情况下,manifest为null,所以tmpManifes的值将会是Ext.manifest的值,而从图中可以知道,Ext.manifes的值是bootstrap,也就是说,现在tmpManifes的值是bootstrap。接下来判断tmpManifes是否为字符串,当前情况下,tmpManifes是字符串,所以要执行判断语句内的代码。先给url赋值,这个由Boot.baseUrl、tmpManifest和“.json”三部分构成,先不管Boot.baseUrl,可以知道,这里要找的是bootstrap.json文件。接下来会调用Boot.fetchSync方法,代码如下:
fetchSync: function(url) { var exception, xhr, status, exception = xhr = new XMLHttpRequest(); try { xhr.open('GET', url, false); xhr.send(null); } catch (e) { exception = } status = (xhr.status === 1223) ? 204 : (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || (self.location || {}).protocol === 'ionp:')) ? 200 : xhr. content = xhr.responseT xhr = // Prevent potential IE memory leak return { content: content, exception: exception, status: status }; },
从代码中的new XMLHttpRequest这语句就知道,这段代码的主要作用就是使用Ajax去加载bootstrap.json文件了。现在假定能正确加载bootstrap.json文件并返回initManifest方法。
在initManifest方法内,接下来要做的是调用JSON.parse将返回的数据解析为JSON对象,并Ext.manifest属性指向该对象。最后将JSON对象返回laod方法。 在load方法的第二句,会先从返回的对象中取出loadOrder的值。在bootstrap.json文件中,loadOrder是一个由对象组成的数组,而每一个对象包含path、requires、uses和idx这4个成员。如果对于Ext JS有一定理解,那么要理解这4个成员不难。成员paths的值就是Ext JS类的脚本的路径,requires和uese指的是这个类所需要的类和使用到的类,而idx则是这个类的唯一标识。在requires和uese中就是使用这个唯一标识来指定所需或使用到的类文件的。 把这个loadOrder取出后,会调用Boot.createLoadOrderMap方法进行处理,代码如下:
createLoadOrderMap: function(loadOrder) { var len = loadOrder.length, loadOrderMap = {}, i, for(i = 0; i & i++) { element = loadOrder[i]; loadOrderMap[element.path] = } return loadOrderM },
代码的作用只是把loadOrder数组转换为对象,对象的属性名称就是类文件的路径,值就是类对象本身。
返回到load方法,在处理完loadOrder数组后,会继续从bootstrap.json文件中把js和css的值取出来,然后合并到resources数组中。在当前项目中,bootstrap.json文件中的js和css的定义如下:
&js&:[{&path&:&app.js&}], &css&:[{&path&:&bootstrap.css&}
这样对于理解后面的循环就容易多了,由于在定义中,没有platform这个成员,所以循环中的第一个判断就会被跳过,直接执行第二个判断了,也就是把路径信息推人urls数组中。
处理完这个,就开始调用Boot.load方法了,代码如下:
load: function (request) { if (request.sync || _syncMode) { return this.loadSync(request); } // Allow a raw array of paths to be passed. if (!request.url) { request = { url: request }; } // If there is a request in progress, we must // queue this new request to be fired when the current request completes. if (_currentRequest) { _suspendedQueue.push(request); } else { Boot.expandLoadOrder(request); var url = request.url, urls = url.charAt ? [ url ] : url, length = urls.length, // Start the counter here. This is reduced as we notify this fellow of script // loads. request.urls = request.loaded = 0; request.loading = request.charset = request.charset || _config. request.buster = (('cache' in request) ? !request.cache : _config.disableCaching) && (_config.disableCachingParam + '=' + (+new Date())); _currentRequest = request.sequential = for (i = 0; i & ++i) { Boot.loadUrl(urls[i], request); } } },
在这段代码中,前面的代码都是与处理请求地址有关,而当这些都准备好了以后,就会调用Boot.loadUrl方法去加载文件了。而在Boot.loadUrl方法内,会调用Boot.create方法去创建加载标记,代码如下:
create: function (url, key) { var css = url && cssRe.test(url), el = doc.createElement(css ? 'link' : 'script'), if (css) { el.rel = 'stylesheet'; prop = 'href'; } else { el.type = 'text/javascript'; if (!url) { } prop = 'src'; if(Boot.hasAsync) { el.async = } } key = key || return _items[key] = { key: key, url: url, css: css, done: false, el: el, prop: prop, loaded: false, evaluated: false }; }, 从代码doc.createElement这句就可以看到,在这里会创建SCRIPT或LINK标记去加载脚本或样式。
这么简单的东西搞得那么复杂的一个原因是要确保类的加载顺序,以确保不会出现类初始化时找不到依赖类的情况。因而,在整个加载过程中,需要监控每个脚本的加载情况,在依赖类没有加载完成之前,不去加载该类。 在bootstrap.json文件中,已经把app.js、bootstrap.css等文件加进去了,所以,在index.html文件中,只需要加载bootstrap.js文件就行了。
至此,我们已经基本了解了Ext JS 5的启动过程了。现在的问题是,我们怎么去加载本地化文件。
01:14&&&[]
Ext.ns('dhcc.license'); dhcc.license.ApplyPanel&=&function(config)&{ &&&var&expander&=&new&Ext.ux.RowExpander({ tpl&:&new&Ext.Template( &&&&&&&&'&p&&b&公司:&/b&&/p&&p&{company}&/p&&br&', &&&&&&&&'&p&&b&申请描述:&/b&&/p&&p&{company}&/p&' ) }); var&_cm&=&new&Ext.grid.ColumnModel( &&&&&&&&[ &&&&&&&&expander, new&Ext.grid.RowNumberer(), {header&:&'申请公司',&dataIndex&:&'company'}, {header&:&'申请单状态',&dataIndex&:&'state'}, //{header&:&'申请时间',&dataIndex&:&'applyDate'} &&&&&] &&&&); var&_store&=&new&Ext.data.ArrayStore({ &&&&&&&&fields&:&[ &&&&{name&:&'company'}, &&&&&&&&&&&&{name&:&'state'}, &&&&//{name&:&'applyDate',&type&:&'date',&dateFormat:&'Y年m月d日'} ], &&&&data&:&[ &&&&&&&&['sz',&'sz'], ['sz',&'sz'], ['sz',&'sz'] ] }); Ext.apply({ renderTo&:&'app', width&:&500, height&:&400, cm&:&_cm, store&:&_store, plugins&:&expander },&config); dhcc.license.ApplyPanel.superclass.constructor.call(this,&config); }; Ext.extend(dhcc.license.ApplyPanel,&Ext.grid.GridPanel,{ });
FB报的错是,cm&is&undefine,可是我有ColumnModel了啊,求人解救我
回复讨论(解决方案)
求解救,明明定义了cm并挂在this里了,快疯了。
我是EXT新手,来学习的,我怎么看你代码有些地方多了逗号啊
-15:01&&&[]
最近的项目都是用Ext&&js来做前台画面显示的,大家有没有这方面的资料,分享一下啦。。。
回复讨论(解决方案)
extjs&&你要哪个版本的,貌似3.0+都收费的吧。
Ext&js教程&百度上有!&&nbsp
-15:01&&&[]
目的:设计模式众多,尝试用博客记录下学到的不同设计模式的优劣,方便以后查阅。 前言:半年前看高程的时候看到设计模式这章,云里雾里,不是看不明白,而是不明白为啥要如此麻烦只为创建一个对象。直到最近完成了自己第一个小项目,才体会到当代码量多起来时没有适当的规范与限制是多么大的灾难。于是重新翻开高程,总结下几种我学到的简单设计模式的优劣。 正文:本文一共介绍7种设计模式以及他们的应用场景、优劣。 1.工厂模式 直接用函数来封装对象,将对象作为返回值。
function person (name,age) { var obj=new Object(); obj.name= obj.age= obj.sayName=function () { alert(this.name); }; } var me=person(&Su&,25);
缺点:对象识别的问题,所有创建出的对象都是Object的实例,不好区分。 2.构造函数模式
function Person (name,age) { this.name= this.age= this.sayName=function () { alert(this.name); }; } var me=new Person(&Su&,25);
优点:运用构造函数模式可以将实例标示为一种特定的类型。 缺点:创建的对象的方法都是私有的,如果只是想产生公用的方法,会造成不必要的性能浪费。 3.原型模式 利用原型链继承
function Person () {} Person.prototype.name=&Su&; Person.prototype.sayName=function () { alert(this.name);} var me =new Person();
缺点:所有属性和方法被实例共享。当属性、方法中包含引用类型的值时,修改一个实例的属性、方法会影响所有其他实例。 4.原型+构造函数模式 私有属性、方法用构造函数产生,公有属性、方法用原型来继承。融合两种方法的优点。
function Person (name,age) { this.name= this.age= } Person.prototype={ constructor:Person, sayName:function () { alert(this.name); } } var me=new Person(&Su&,25);
缺点:注意引用类型值的原型继承。 ps:上图代码重写了Person构造函数的原型对象,将原型对象指针指向了一个对象,所以constructor属性此时指向Object而不是Person,所以要显式的将其设置成Person。 5.动态原型模式 本质上还是构造函数,只在指定方法不存在时在原型对象中添加他。
function Person (name,age) { this.name= this.age= if (typeof this.sayName!=&function&) { Person.prototype.sayName=function () { alert(this.name); } } } var me =new Person(&Su&,25);
缺点:不能使用对象字面量重写原型对象。因为这会使实例的指针指向新的原型对象。也就是说上图中原型对象中添加的sayName方法会失效。 6.寄生构造函数模式 &调用时使用new操作符,除此以外我看不出和工厂模式有什么区别。望高人指点。
function person (name,age) { var obj=new Object(); obj.name= obj.age= obj.sayName=function () { alert(this.name); }; } var me=new person(&Su&,25); //这里使用new操作符
7.稳妥构造函数模式 没有公共属性,禁用this,仅暴露必须的API用于数据调用。适用于对安全有需求的领域。
function Person (name) { var o=new Object(); o.sayName=function () { alert(name); } } var me=Person(&Su&);
如图代码,只能通过sayName方法才能访问到内部的name属性。
13:09&&&[]
,可以是 字符串 或者 一个React组件类型,为字符串的时候,只能是标准的HTML标签名称,如p, div
props: 可选的JSON对象,指定元素的附加属性,如样式,CSS类名等,CSS类名要用className,而不是用class,因为class是JS保留字。可设置成null
19:53&&&[]
运行命令即可避免该异常出现。
& 然后再打开浏览器输入浏览地址:http://127.0.0.1:3000或http://localhost:3000 即可运行testnode.js文件. 运行效果如下:
好,看起来一切运行正常,今天对Node.js的初探就到这里,在以后的文章里会
15:30&&&[]
仅仅只是一个简单的hello world. & js代码很简单: &
&!DOCTYPE&HTML&&& &html&lang=&cn&&&& &&lt
18:41&&&[]
一个Ext&js的诡异问题:在火狐下,警告框的右上角没有X图标,但当鼠标指针移到上面时还是可以关闭警告框
回复讨论(解决方案)
浏览器是火狐,ie根本不显示这个警告框
extjs版本是4.1.1
css样式文件有没有引入?
你的警告框是继承哪个类的?
-14:10&&&[]
前言 &&&&& 在学习慕课网视频和Cnode新手入门接触到爬虫,说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http、网页分析工具cherrio。 使用http直接获取url路径对应网页资源,然后使用
04:56&&&[]
@author mrbean 例子均来源于github&parallel.js
&   昨天写的第一篇今天一看居然有50+的阅读量了,感觉很激动啊,但是也有点害怕毕竟这只是自己笔记性质的一点东西,所以赶紧拿起来再看看。其实自己也没什么把握,所以希望大家看的话有什么不同的以及
13:39&&&[]

我要回帖

更多关于 ext js权威指南 的文章

 

随机推荐