注:由于博主最近在做wake框架方面的工作,所以本博中的代码实例均以wake框架中的extjs做展示。并不影响extjs本身的学习。
什么是ExtJS?
ExtJS是一个用javascript、CSS和HTML等技术实现的主要用于创建用户界面,且与后台技术无关的前端Ajax框架。
在Extjs 4.x版本中引入了MVC开发模式,开始将一个JS(Extjs)应用程序分割成Model-View-Controller三层,为JS应用程序的如何组织代码指明了方向,同时使得大规模JS代码变得更加易于重用和维护;这就是Extjs MVC开发模式的初衷。
一、创建MVC模式的结构
1、创建目录结构
在模块根目录下,分别创建controller、model、store和view。分别代表控制器层、模型层、存储层和视图层。之间的相互关系:
2、创建容器JSP
在模块根文件夹下,创建jsp文件作为容器。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <wake:import cmp="wake-debug.cmp"/> <wake:import path="pages/csp/vmorder/myvms" apps="myvms" ctrls="myvmsCtrl" views="myvmsIndex,myvmsLook,myvmsMonitor" stores="myvmsStore" models="myvmsModel"/> </head> <body> </body> </html>
1、wake:import 相当于
<script language="javascript" src=“xxx.js" type="text/javascript"></script>
2、body内为空,只作为容器,由js文件填充。
3、创建入口JS
在模块根文件夹下,创建js文件。
var app = null; var control = null; Ext.application({//创建应用 name : 'MYVMS', controllers : ['MyvmsCtrl'],//创建ctrl launch : function() {//启动应用 app = this; control = this.getController("MyvmsCtrl"); var viewPort = Ext.create('Ext.container.Viewport', {//创建view border : 0, layout : 'fit', items : [{ id : 'myvmsIndex', xtype : 'myvmsindex'//组件别名 }] }); Ext.getCmp('myvmsGrid').getPageBar().setQueryFunction(control.doQueryMyvms); control.doQueryMyvms();//可以执行方法 } });
具体含义在后面会详细说明
二、view层
组件
学习ExtJS就是学习组件的使用。每种组件都有指定的xtype属性值,通过该值可以得到一个组件的类型或者定义一个指定类型的组件。组件大致分为四大类,即容器类组件、工具栏及菜单栏组件、表单及元素组件、其他组件。
组件的创建
通过create关键字来创建;
Ext.create( ... );
通过define关键字来定义:
Ext.define( ... );
布局
fit布局
在Fit布局中,子元素将自动填满整个父容器。注意:在fit布局下,对其子元素设置宽度是无效的。如果在fit布局中放置了多个组件,则只会显示第一个子元素
Border布局
border布局也称边界布局,他将页面分隔为west,east,south,north,center这五个部分,我们需要在在其items中指定使用region参数为其子元素指定具体位置。 center 区域是必须使用的,而且center 区域不允许折叠。Center区域会自动填充其他区域的剩余空间。尤其在Extjs4.0中,当指定布局为border时,没有指定center区域时,会出现报错信息。
Accordion布局
accordion布局也称手风琴布局,在accordion布局下,在任何时间里,只有一个面板处于激活状态。其中每个面边都支持展开和折叠。
Card布局
这种布局用来管理多个子组件,并且在任何时刻只能显示一个子组件。这种布局最常用的情况是向导模式,也就是我们所说的分布提交。
Anchor布局
anchor布局将使组件固定于父容器的某一个位置,使用anchor布局的子组件尺寸相对于容器的尺寸,即父容器容器的大小发生变化时,使用anchor布局的组件会根据规定的规则重新渲染位置和大小。
Absolute布局
Absolute布局继承Ext.layout.container.Anchor 布局方式,并增加了X/Y配置选项对子组件进行定位,Absolute布局的目的是为了扩展布局的属性,使得布局更容易使用
Column布局
Column布局一般被称为列布局,这种布局的目的是为了创建一个多列的格式。其中每列的宽度,可以为其指定一个百分比或者是一个固定的宽度。
示例
Ext.define('MYVMS.view.MyvmsIndex', { extend : 'Ext.container.Container', alias : 'widget.myvmsindex',//别名 layout : 'border', initComponent : function() {//构造函数 var me = this; me.items = [me.createQueryField(), me.createShow()]; me.callParent(); }, //自定义方法 createQueryField : function() { var me = this; me.queryField = Ext.create("Ext.form.Panel", { id : 'searchMyvms_form', name : 'queryFieldForm', region : 'north', height : 150, bodyStyle : 'padding :5 5 5 5 ', defaults : { labelWidth : 60, padding : '15 30 10 30', columnWidth : 0.4,// 以25%的宽度赋给每个组件 xtype : 'textfield', labelAlign : 'center', width : 200 }, items : [{ fieldLabel : '订单编号', name : 'orderNumber', id : 'orderNumber', xtype : 'textfield', text : null, align : "center", //colspan:2, margin: '5 5 5 30', }, ... ] }); return me.queryField; }, createShow : function() { ... }, createShowMyvmsGrid : function() { ... } });
三、Model层
定义数据模型,一般我们会重写Ext.data.Model,进行实现自己的model层
Ext.define('MYVMS.model.MonitorModel',{ extend: 'Ext.data.Model', fields:[ {name : 'id',type:'int'},//监控信息id {name : 'vmitemMark',type:'string'},//云主机标示,唯一 {name : 'cpuusagerate',type:'double'},//cpu使用率 {name : 'memusagerate',type:'double'},// 内存使用率 {name : 'timepoint',type:'string'}// 时间点 ] });
四、Store层
用来访问model,与model一一对应。虽然store不是mvc中必须的步骤,但是作为数据仓库,store起到了数据存取的作用,grid、form等展现的数据都是通过store来提供的,因此store在extjs mvc开发模式中是必不可少的。
Ext.define('MYVMS.store.MyvmsStore',{ extend:'Ext.data.Store', model:'MYVMS.model.MyvmsModel' });
五、Controller层
controller作为连接model、store和view的桥梁,在mvc开发模式中起到了至关重要的作用。如果说model定义了数据模式、store提供了数据存取的方法、view用来展示数据,那么controller将用来控制具体的数据操作。
var path = "register/";// 资源请求路径 Ext.define('CONFIG.controller.ConfigCtrl', { extend : 'Ext.app.Controller', views : ['ConfigIndex','ConfigDetail','ChoseWebServer','ChoseDBServer'],// 声明该控制层要用到的view stores : ['ConfigStore','WebServerStore','DBServerStore'],// 声明该控制层要用到的store init : function() { this.control({ '#showAllForConfig' : { click : this.doQuery//显示所有 } }); }, doQuery : function() {//自定义方法 var configIndex = Ext.getCmp('configIndex'); // 开启表格遮罩层 configIndex.setLoading(true); // 获取查询条件 var configGrid = configIndex.configGrid; var pagingBean = configGrid.getPageBar().getPagingData(); var url = restPath + path + "findAllwebapp"+ "?paging="+ Ext.JSON.encode(pagingBean); /** 组装请求对象,并调用框架的请求方法发送请求 */ wake.ajax({ contentType : 'application/json',// 声明提交的数据类型 dataType : 'json',// 声明请求的数据类型 type : "GET", url : url, timeout : 30000,// 30秒钟的查询超时 success : function(data) { if (data) { configGrid.getStore().loadData(data.appList);// 加载表格数据 configGrid.getPageBar().setPagingData(data.pagingBean);// 加载分页数据 } // 关闭遮罩 并提示 wake.showMessage("查询完毕"); configIndex.setLoading(false); }, error : function() {// 发生异常时 // 关闭表格遮罩层 configIndex.setLoading(false); } }); }, });