web客户端程序总是很难组织和维护,当越来越多的开发人员和功能加入到当前项目时,会发现项目正在慢慢脱离你的控制,ExtJS4用新的mvc架构使得代码管理以及编写都变的相对简单。在这篇博文里,我会把extjs的mvc和web开发中的mvcmvc做一定的对比,至于mvc的解释,在extjs4里简单说明如下:
M-model:字段集合以及数据,可以理解我j2ee开发中的实体类。在Extjs中通常与Stores结合使用。
V-view:各种UI组件
C-controller:这里是放逻辑代码的主要地方,可以理解程struts中的action或者是springmvc中的controller,这两者干的事就是业务处理,其中看可能会引用到实体类和Dao类,在extjs中model和stores类似,所以在示例里你会看到,控制器里总会有关于stores和model的初始化,还有就是处理完逻辑代码后将结果渲染到视图。
下面就以extjs指南中的例子来说明mvc
1.文件结构:我机器上的文件结构如下所示
index-mvc.html
<html> <head> <title>Account Manager</title> <link rel="stylesheet" type="text/css" href="resources/css/ext-all.css"> <script type="text/javascript" src="resources/js/ext-debug.js"></script> <script type="text/javascript" src="app-mvc.js"></script> </head> <body></body> </html>
2.在app-mvc.js中创建应用
每个ExtJS4的web应用都是从Applecation类的实例开始的,它包含了应用的全局设置(例如应用名),并维护所有的m,v和c。它也可以包含launch方法,当所有都加载完毕,launch方法将会自动运行。
上面创建的app可以帮助管理用户,首先需要为当前应用选择一个全局名字空间(相当于java顶层包),所有的Extjs4应用应该使用它,所有的应用需要的类都放置在这里。一般都是用短名称的全局变量,上面图中用的AM和文档中的一样。
app-mvc.js
//应用从这里开始 Ext.application({ // 相当于java中import,导入要创建的类,动态加载 requires:['Ext.container.Viewport'], // 应用名称 name:'AM', // 应用文件所在路径 appFolder:'app', // 控制器,类文件在app/controller/UserController.js controllers:[ 'UserController' ], // 这个所有加载完毕最后执行 launch:function(){ console.log("应用程序初始化开始"); Ext.create('Ext.container.Viewport',{ //创建窗口 layout:'fit', items:[ { xtype:'userlist', // title:'Users', // html:'List of users will go here' } ] },function(){console.log("create Viewport complete");}); //这个随便写的 } });
上面是完整的 代码,以下的代码也是,没有按指南上一步一步下来,在上面的代码中,首先调用Ext.application去创建Application的新实例,传递了一个 appname,值为AM,该实例会自动设置一个全局变量AM,并注册名字空间到Ext.Loader,通过aooFolder配置项设置与app相关的路径,并提供了一个见的lauch方法,让他去创建一个可以覆盖整个页面并包含一个Panel的Viewort,作为主框架。
3.定义控制器类
//控制器类 Ext.define('AM.controller.UserController', { // 继承的父类 extend: 'Ext.app.Controller', // 视图-控制器需要渲染的视图 views:[ 'user.List', 'user.Edit' ], // 在控制器里加入数据存储 -可以理解 stores:[ 'User' ], models:[ 'User' ], // 初始化 init: function() { console.log("控制器初始化开始"); this.control({ 'viewport > panel':{ render:this.onPanelRender }, 'userlist':{ itemdblclick:this.editUser }, 'useredit button[action=save]':{ click:this.updateUser } }); }, // 动作 onPanelRender:function(){ console.log("panel render"); }, //编辑用户 editUser:function(grid,record){ var view=Ext.widget('useredit'); view.down('form').loadRecord(record); }, updateUser:function(button){ console.log("begin update"); var win=button.up('window'); form=win.down('form'); record=form.getRecord(); values=form.getValues(); record.set(values); win.close(); this.getUserStore().sync(); } });
控制器在extjs中相当重要,他像胶水一样将整个应该的各个方面绑定到一起。它负责监听事件(通常来自视图)并对相应的事件采用对应动作进行处理。
当用户通过访问index-mvc.html加载应用时,UserController将会自动加载(因为我们在app-mvc.js里把它作为配置项的)并且控制器的init方法会在应用的launch方法执行之前执行。
控制器的init方法是设置控制器如何与视图交,通常和另一个控制器方法control结合使用,control方法使得事件监听和事件处理变的容易。程序中的console.log在chrome下的控制台中会看到信息。
上面的init中使用了新的组件查询引擎,它使得从页面中获取组件引用变得快速简单,它允许你通过类似css的选择器来查找页面上匹配的组件。程序中的'viewport > panel'可以理解为,找到Viewprot下的每一个panel,然后提供了一个对象去映射事件名(render)和事件处理函数,效果就是无论何时只要有与选择器有匹配组件,就会触发render事件,并调用onPanlelRender函数进行处理。
4.定义视图类一List(用户列表视图)
视图无非就是个ui组件,通常定义成extjsui组件的子类,在这里代码如下: