Ext JS的认识
1.ExtJS写起来代码就像 Java 一样,非常严谨,非常面向对象。缺点就是在前端 JS库中属于比较重量级
2.Ext JS就是一个客户端的 JavaScript 框架
Ext JS的优点:
1. 跨浏览器支持
2. 丰富的UI组件
3. 双向数据绑定
双向数据绑定意味着当视图View的数据发生变化,你的模型model将自动更新。同样的,当你的应用更新这个模型model,这个数据也将自动传递到view
就拿编辑页面来举例。当这个页面(view)加载,这时已经渲染了来自模型(model)的数据到HTML,并且当用户在页面(view)上更新这个数据,这时候你需要更新你的模型(model),但如果你使用Ext JS将不需要你自己去做这些编程。
4. JavaScript的架构模式(MVC/MVVM)
MVC(Model View Controller)/MVVM(Model View View Model)
5. 访问DOM变得容易
6. 客户端路由
路由可以在服务端也可以在客户端。通常客户端路由都是用单页式应用实现的。Single-Page Application(SPA)。
7. 支持无障碍访问
无障碍访问特性意味着这个应用程序的内容必须是可以方便的让视力受损的人借助辅助设备访问(例如屏幕阅读器)。而开发一个应用程序能够很好的支持无障碍特性是非常困难的。这里 Ext JS已经为你做了。
在美国,如果你开发的软件供联邦和州政府职员使用,在绝大多数情况下,你需要确保你的程序是支持无障碍访问特性的。这一点,很少 JavaScript框架能对无障碍访问特性有较好的支持。而 Ext JS 提供了完美的无障碍访问支持。并且所有的控件都可以支持,不需要你做任何额外的编码。
介绍Ext JS
Ext JS 作为一个一站式的开发富UI应用的框架。
在Ext JS中,你写的代码基本上就是JavaScript,因为你不需要写HTML。Ext JS附带一组庞大丰富的UI组件,这时你的开发过程中会节约你相当多的时间。
在Ext JS 6 中最重要的变化是结合了两个框架:Ext JS和Sencha Touch合并成为了一个框架。Ext JS主要用于桌面级的web应用。Sencha Touch主要用于移动设备。
在Ext JS 6合并后两个框架通用的代码作为一个核心,并引入了一个toolkit(工具箱)的概念。Toolkit是一个可视化的组件包。
Ext JS 6有两个工具包:classic(古典)存放原来Ext JS的可视化组件。Modern(现代)存放原来Sencha Touch的可视化组件。
Ext JS 6还带来了一个新的SASS编译其叫做Fashion,以及3D图表的改进等等。
通用应用
在Ext JS 6中你可以创建一个通用的应用,通用的应用是指同时支持桌面和移动设备。这时候将会同时应用两个工具包。你可以添加一下的构建配置(这个配置在程序根目录app.json配置文件中,详细的后面会讲到),来指定构建使用的工具包主题:
"builds": {
//这里就很简单了,如果你只想用 classic那么就注释 modern 的配置即可。
"classic":{
"toolkit": "classic",
"theme": "theme-triton"
},
"modern":{
"toolkit": "modern",
"theme": "theme-neptune"
}
}
这应做的思路就是,在Ext JS这个框架里用这两个工具包分别对应桌面和移动设备。
设置ExtJS开发环境
1. 安装Sencha Cmd
Sencha Cmd虽然不是开发Ext JS应用的必备工具,但是它会让你的开发工作非常轻松,它包括以下功能,包括管理,JS编译器,构建脚本,主题等等。
在安装Sencha Cmd之前,你需要先安装JRE环境,如果你使用的是 Sencha Cmd 5,那么你还需要安装 Ruby。
安装完成Sencha Cmd后在命令行输入一下命令(Sencha Cmd需要环境配置)
1 |
sencha which |
正常情况下应该显示类似以下的代码:
SenchaCmd v6.0.0.92
/bin/Sencha/Cmd/6.0.0.92/
如果报错,你应该配置环境变量
用Sencha Cmd生成第一个Ext JS应用
打开命令行窗口键入以下命令:
1 |
sencha generate app --ext MyApp ./myapp |
运行上面的命令将会创建名为 MyApp 的 Ext JS应用,应用所有的文件都放在当前目录下名为 myapp 的文件夹。
上面的命令生成的 Ext JS 应用代码,包含两个工具包:classic和 modern。因为你不明确指定需要用那个工具包的时候,默认创建的就是通用的应用。如果你需要指定使用 classic或者 modern 工具包。那么用 –modern或者 –classic 参数,如以下命令所示:
1 |
sencha generate app --ext --modern MyApp ./myapp |
当你第一次运行这个命令时,这应该会自动下载 Ext JS 6。如果没有自动下载,那你需要手动的取下载 Ext JS 6,这里贴出来 GPL协议的 Ext JS 6 官网下载地址http://cdn.sencha.com/ext/gpl/ext-6.0.0-gpl.zip这里下载后解压,这时候生成 Ext JS 应用时就可以使用以下命令以指定 SDK的形式生成了:
1 |
sencha -sdk /path/to/sdk generate app MyApp /path/to/myapp |
SenchaCmd 支持 Ext JS 4.1.1a以及更高版本,支持 Sencha Touch 2.1 以及更高版本。在你的电脑里可以有多个版本的 SDK。上面的命令是基于一个特定的 Sencha SDK 来生成的 Ext JS应用。
下面的例子,在目录 /projects/extjs/myapp下生成名为 MyApp 的 Ext JS应用:
1 |
sencha -sdk /bin/Sencha/ext/6.0.0/ generate app MyApp /projects/extjs/myapp |
OK,现在可以查看已经创建的应用了,运行以下命令:
1 2 3 |
cd /projects/extjs/myapp
sencha app watch |
在浏览器输入默认 URL (http://localhost:1841),如图所示
,看到类应用会自动检测并为你展示 classic工具包的UI。如果访问是来自一个移动端浏览器,它将展示 modern工具包。如何在电脑上看 modern 风格的应用呢?附加参数 (http://localhost:1841?profile=modern),你将看到以下截图:
MyApp应用的整体目录中应包含了model,store,和application.js.可以把store看成一个model实例的集合,store是为你的程序功能提供并加载数据用的,可以把store看为一个数据源,它支持排序,过滤,分页等,经常用到store的就是grid组件。
在下面截图中,有 classci和 modern 这两个文件夹。这两个文件夹包含使用不同工具包时写的 view(视图)代码,例如你 classic风格的 view(视图)就应该写在 classic 目录下,modern风格的 view(视图)就应该写在 modern 目录下。
Class和modern都包含src目录,而你的view(视图)就应该写在src里面。
这个main.scss文件是样式文件,在classic和modern工具包都存在,对应桌面和移动设备的样式。
在根目录也有一个sass文件夹,那里是放置所有设备公用的样式。
SASS(Syntactically(语法)Awesome(极好的) Stylesheets(样式表))是一种样式语言。
class和modern目录,都不是Ext JS框架的工具包源码。classic 和moden两个工具包的源码都在根目录ext文件夹里边
应用的体系结构
Ext JS提供支持两种应用框架MVC和MVVM。
Model(模型)
代表数据层,model保存的数据主要包含数据验证和逻辑,model经常用于store中,可以说store是多个model的集合。
View(视图)
这一层是用户界面,包含button,form,和message box等各种组件。
Controller(控制层)
控制层主要处理view(视图)相关的逻辑。
View model(视图模型)
view model封装了view(视图)所需的展示逻辑,绑定数据到view并且每当数据改变时处理更新。
如果你打开sass的文件夹下的app.js,你将会看到下面的代码。这是Ext JS应用的启动代码:
1 2 3 4 5 6 7 8 |
Ext.application({ name : 'MyApp', extend : 'MyApp.Application', requires : [ 'MyApp.view.main.Main' ], mainView : 'MyApp.view.main.Main' }); |
在上面的代码中,name定义了程序的名称,extend表示继承了MyApp.Application类,这个类定义在app文件夹下名为Application.js。
requires部分指定了这个类所需要的类列表。这样在requires里面添加的类在当前类中首次实例化时,会去加载它,其实可以把request的作用理解为java中的import关键字。mainView指定的是要初始化的view(视图)。
打开app文件夹,将会看到文件Application.js,和model,view,store等
下面是Application.js文件里的代码:
1 2 3 4 5 6 7 8 9 10 |
Ext.define('MyApp.Application', { extend: 'Ext.app.Application', name: 'MyApp', stores: [ // TODO: add global / shared stores here ], launch: function () { // TODO - Launch the application } }); |
这里我们看到MyApp.Application继承了Ext.app.Application。这个launch函数是在Ext.app.application类里。这个函数将在页面加载完成后调用。
视图模型—MainModel.js
在看一下\app\view\main\目录下的MainModel.js 文件。这个类是Main视图的viewmodel(视图模型)。这个视图模型继承自Ext.app.ViewModel. 代码如下所示:
1 2 3 4 5 6 7 8 |
Ext.define('MyApp.view.main.MainModel',{ extend : 'Ext.app.ViewModel', alias : 'viewmodel.main', data : { name : 'MyApp', loremIpsum : 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' } }); |
控制器-MainController.js
这个类是 Main 视图的控制器。在下列代码中你可以看到 onItemSelected函数,这个函数将在视图里的 grid 中选中某一项时触发调用。
1 2 3 4 5 6 7 8 9 10 11 12 |
Ext.define('MyApp.view.main.MainController', { extend : 'Ext.app.ViewController', alias : 'controller.main', onItemSelected : function(sender, record) { Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this); }, onConfirm : function(choice) { if (choice === 'yes') { // } } }); |
我们可以看到 extend 继承了 Ext.app.ViewController这个类。Ext JS 中有两种类型的控制器: Ext.app.ViewController和 Ext.app.Controller。
视图 – Main.js
如果你用的是Sencha Cmd 6生成的通用应用,那么将会有两个Main.js文件,分别在\modern\src\view\main\和\classic\src\view\main\ 目录下面。
Ext JS 6 合并了 Ext JS和 Sencha Touch 为一个框架。这两个框架合并后共用一个核心,剩下的代码则分为两部分 classic和 modern。传统的 Ext JS代码移动到 classic 工具包,而 modern的代码支持触摸和 HTML5 在 modern工具包。所以这里需要两个工具包,程序会根据访问设备自动使用对应的工具包里的 UI类(view)。
应用分两个工具包并共享核心资源和逻辑,这是通用应用。
现在我们看一下在 modern 下的 Main.js 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
Ext.define('MyApp.view.main.Main', { extend : 'Ext.tab.Panel', xtype : 'app-main', requires : [ 'Ext.MessageBox', 'MyApp.view.main.MainController', 'MyApp.view.main.MainModel', 'MyApp.view.main.List' ], controller : 'main', viewModel : 'main', defaults : { styleHtmlContent : true }, tabBarPosition : 'bottom', items : [{ title : 'Home', iconCls : 'fa-home', layout : 'fit', items : [ { xtype : 'mainlist' } ] }, { title : 'Users', iconCls : 'fa-user', bind : { html : '{loremIpsum}' } }, { title : 'Groups', iconCls : 'fa-users', bind : { html : '{loremIpsum}' } }, { title : 'Settings', iconCls : 'fa-cog', bind : { html : '{loremIpsum}' } }] }); |
这个Main视图是一个tab panel,因为它继承了Ext.tab.Panel。这个类有属性controller,viewmodel,requires配置了需要依赖的类。创建了四个tab页(items属性),并且绑定了数据ViewModel里的loremlpsum属性。
接着看一下在 \classic\src\view\main\下的 Main.js 文件内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
Ext.define('NewApp.view.main.Main', { extend : 'Ext.tab.Panel', xtype : 'app-main', requires : [ 'Ext.plugin.Viewport', 'Ext.window.MessageBox', 'NewApp.view.main.MainController', 'NewApp.view.main.MainModel', 'NewApp.view.main.List' ], controller : 'main', viewModel : 'main', ui : 'navigation', tabBarHeaderPosition : 1, titleRotation : 0, tabRotation : 0, header : { layout : { align : 'stretchmax' }, title : { bind : { text : '{name}' }, flex : 0 }, iconCls : 'fa-th-list' }, tabBar : { flex : 1, layout : { align : 'stretch', overflowHandler : 'none' } }, responsiveConfig : { tall : { headerPosition : 'top' }, wide : { headerPosition : 'left' } }, defaults : { bodyPadding : 20, tabConfig : { plugins : 'responsive', responsiveConfig : { wide : { iconAlign : 'left', textAlign : 'left' }, tall : { iconAlign : 'top', textAlign : 'center', width : 120 } } } }, items : [ { title : 'Home', iconCls : 'fa-home', items : [ { xtype : 'mainlist' } ] }, { title : 'Users', iconCls : 'fa-user', bind : { html : '{loremIpsum}' } }, { title : 'Groups', iconCls : 'fa-users', bind : { html : '{loremIpsum}' } }, { title : 'Settings', iconCls : 'fa-cog', bind : { html : '{loremIpsum}' } } ] }); |
上面代码中,items 中的代码几乎和 modern工具包中的是一样的。此外,这个文件有些配置是专用于支持响应设计的。下列代码告诉框架使用的 ui 组件为 navigation:
ui: ‘navigation’
Sencha命令格式
Sencha命令采用的格式:
sencha[category] [command] [options…] [arguments…]
Help
键入以下命令,你将获取一个 categories(类别)列表,一个顶层的 commands(命令)列表,一个可用的 options(选项)列表:
1 |
sencha help |
获取一个特定类别的帮助信息,类别名称紧随在 help后面,例如获取一个类别 app 的帮助信息,运行下列命令:
1 |
sencha help app |
将产生以下输出:
如果你想进一步获取 app 命令下的子命令的帮助信息,你只需要在最后添加子命令例如 clean,如以下代码所示:
1 |
sencha help app clean |
将产生以下输出:
升级一个现有的 ExtJS 应用到最新版本,需要先进入到你的 ExtJS 工程目录,使用一下命令:
1 |
sencha app upgrade 后面跟上 sdk路径 |
不加路径的话,就会自动从官网下载最新版本的 ExtJS 框架。
注意:如果 sencha cmd 与要升级到的 ExtJS 框架版本不兼容,需要先升级 SenchaCMD 再升级 ExtJS。
Sencha Cmd 支持 Ext JS 4.1.1a 及更高版本和支持 Sencha Touch 2.1 及更高版本。你电脑上可以存在多个版本的 SDK。这是基于 Sencha SDK生成应用的命令格式,例如 Ext JS 或者 Sencha Touch:
1 |
sencha -sdk /path/to/sdk generate app [--modern/classic] MyApp /path/to/ myapp |
这个示例代码将在目录 /Users/SomeUser/projects/extjs/myapp下生成名为MyApp的 Ext JS 6 应用 :
1 |
sencha -sdk /Users/SomeUser/bin/Sencha/Cmd/repo/ |
运行下列命令将进行构建 HTML,JS,SASS等等:
1 |
sencha app build |
使用 Sencha Cmd 6 构建 Ext JS 6 应用,你还可以运行下列命令选择构建 moern 或 classic 风格的应用:
1 2 |
sencha app build modern sencha app build classic |
这里说一下,modern 和 classic 的构建配置在 app.json。 默认 Sencha Cmd 运行两个构建配置: classic 和 modern 。如果需要你也可以在 app.json中添加额外的构建配置。
watch 命令用于重新构建并启动应用。这不仅会启动应用程序,还监视任何代码更改,一旦代码改变,浏览器刷新将包括最新的代码:
1 |
sencha app watch |
在 Sencha Cmd 6 和 Ext JS 6,你也可以运行下列命令选择 modern 或 classic:
1 2 |
sencha app watch modern sencha app watch classic |
用Sencha Cmd,你可以生成 Ext JS代码,例如 view,controller,model:
1 2 3 4 5 |
sencha generate view myApp.MyView
sencha generate model MyModel id:int,fname,lname
sencha generate controller MyController |
当你生成 model 时如果不指定字段类型,默认类型是 string。
Sencha Cmd 升级 SDK 的版本是很容易的。使用这个升级命令将你的程序升级到新框架:
1 |
sencha app upgrade [ path-to-new-framework ] |
你可以使用浏览器默认的调试器来调试 Ext JS 代码,但是使用火狐浏览器的 firebug 插件再安装 Illumination或者使用 Chrome 的 Inspector插件调试这将会容易得多。
Illumination
Illumination 是一个第三方工具。它并不是 Sencha 的一个产品,目前它只支持火狐浏览器。
这有些 Illumination 的特性,这将减少你在调试上花的时间。
Illumination 会很容易识别出 Ext JS 组件,所以在 illumination 标签页你能看到 Ext JS 组件名称,例如 Ext.panel.Panel 而不是像在 firebug的 DOM 页里那样显示成Object。
如果在 Illumination 窗口你鼠标悬停在任意对象上,将会突出高亮在 HTML 页面中的组件。
一个 Ext JS 组件是由数个 HTML元素组成的。如果你在页面右击选择使用 firebug 查看元素,你会看到元素是嵌套在 Ext JS 组件里,但是如果你选择 Illumination来查看元素,会直接显示 Ext JS 组件,这更有便于检查组件的方法属性和事件。
firebug DOM 标签页里对象是如何展示的:
再看一下 Illumination标签页下对象是如何展示的,你会发现所有组件都显示在下列截图中:
尽管 Illumination使调试 Ext JS应用变得容易,但是并不是必须用它。它并不是免费的,你不想购买的话,仍然可以使用 firebug调试,但你也许会多花一些时间调试,或者使用 App Inspector 插件或者 SenchaFillde 调试。然并卵,我还是建议使用 firebug就行了。
App Inspector 是一个由 Sencha 开发的免费的 Chrome 插件。它支持所有 Illumination 支持的功能。
相比使用 Illumination一些信息在 AppInspector查找更容易方便,并且使用 Illumination 比使用 App Inspector 载入程序时间更长。
App Inspector 的截图:
这是另外的一个调试工具。这也是一个在线的基于 web 的 IDE 并提供了一些调试功能,如下图:
开发 IDE
尽管你可以使用任何简单的文本编辑器来编写 Ext JS 代码,使用 IDE 开发肯定更简单。Sencha 为JetBrains 提供 Sencha JetBrains 插件支持,例如 IntelliJ,WebStrome,PHPStorm,和 RubyMine。
这里为大家推荐Visual Studio Code这个免费的IDE工具。