摘要:接著來(lái),上一篇搭建了基本的項(xiàng)目骨架,到最后,其實(shí)啥也沒(méi)看見(jiàn)。。。目標(biāo)全屏顯示左側(cè)導(dǎo)航菜單,右側(cè)標(biāo)簽頁(yè)切換操作內(nèi)容區(qū)域。一般模型與你后臺(tái)返回的數(shù)據(jù)結(jié)構(gòu)一一對(duì)應(yīng)。給其他組件提供一致接口使用數(shù)據(jù)。整個(gè)構(gòu)成一個(gè)所謂的。
接著來(lái),上一篇搭建了基本的項(xiàng)目骨架,到最后,其實(shí)啥也沒(méi)看見(jiàn)。。。目標(biāo)
書(shū)接上回,開(kāi)始寫(xiě)UI效果。
全屏顯示、左側(cè)導(dǎo)航菜單,右側(cè)標(biāo)簽頁(yè)切換操作內(nèi)容區(qū)域。包含header和footer
導(dǎo)航菜單動(dòng)態(tài)ajax產(chǎn)生,點(diǎn)擊對(duì)應(yīng)菜單可以動(dòng)態(tài)加載js資源或者數(shù)據(jù)
不要太丑?。。。?/p> 先扯點(diǎn)概念:
一些基本的Extjs概念本文不會(huì)去講,請(qǐng)參考官網(wǎng)API文檔。
但是對(duì)于用java的同志來(lái)說(shuō),看extjs的結(jié)構(gòu)應(yīng)該是很容易的
定義與創(chuàng)建 define vs create
///////extjs Ext.define("Cat",{//定義一只貓 name:"小甜甜"http://名字 }) ///////java class Cat(){//定義一只貓 private String name; }
///////extjs Ext.create("Cat",{//創(chuàng)建一只貓 name:"牛夫人"http:// }) ///////java Cat cat= new Cat(); cat.setName="牛夫人";
Model模型是個(gè)啥?
直白點(diǎn)說(shuō)吧,模型就是模型,,就是實(shí)體類(lèi),就是entity,就是POJO,,,,就是.......
總之,模型是用來(lái)定義一個(gè)東西的屬性的。一般模型與你后臺(tái)返回的數(shù)據(jù)結(jié)構(gòu)一一對(duì)應(yīng)。
比如:一個(gè)用戶模型:
Ext.define("luter.model.User", { extend: "Ext.data.Model", fields: [ {name: "id", type: "string"},//用戶id {name: "username", type: "string"},//用戶名 {name: "gender", type: "string"},//性別 {name: "real_name", type: "string"}//真實(shí)姓名 ] });
要模型干啥?哎,開(kāi)始我也這么想過(guò),后來(lái)看到store
Store是干啥的?
好了,你有數(shù)據(jù)庫(kù),你有后臺(tái),你甚至都用js定義了數(shù)據(jù)模型(Model),那你數(shù)據(jù)怎么來(lái)?
Store簡(jiǎn)單理解,就是干這個(gè)的,Store用來(lái)獲取數(shù)據(jù),管理數(shù)據(jù),前端保存數(shù)據(jù)。給其他組件提供一致接口使用數(shù)據(jù)。Store定義了數(shù)據(jù)怎么獲取數(shù)據(jù)、拿到后如何處理數(shù)據(jù)。如下例:
//定義一個(gè)user store Ext.define("luter.store.User", { extend: "Ext.data.Store", autoLoad: false, model: "luter.model.User",//這就是user model, 用戶模型 pageSize: 15,//分頁(yè)頁(yè)面大小 remoteSort: true,//服務(wù)端排序 sortOnLoad: true, proxy: {//proxy規(guī)定了從什么地方以什么方式獲取數(shù)據(jù),并且返回?cái)?shù)據(jù)應(yīng)該如何解析獲取 type: "ajax", actionMethods: { create: "POST", read: "POST", update: "POST", destroy: "POST" }, api: { read: "app/testdata/user.json" }, reader: {//返回?cái)?shù)據(jù)如何讀取 type: "json", root: "root", successProperty: "success", totalProperty: "total" }, listeners: {//當(dāng)發(fā)生ajax異常的時(shí)候,回調(diào)處理。 exception: function (proxy, response, operation, eOpts) { DealAjaxResponse(response); } } }, sorters: {//排序規(guī)則。 property: "id", direction: "DESC" } });
view是什么?
view就是。。。。。。UI?。。?!grid啊、button啊、panel啊、tree啊 form啊。。。等等。。。。
顯示數(shù)據(jù),接受用戶操作,給用戶操作反饋....反正用戶看到的地方,就是view
:>理解沒(méi)?
新建入口文件app.js對(duì)于extjs而言,一個(gè)應(yīng)用也就是application,對(duì)應(yīng)Ext.Application類(lèi)。一個(gè)應(yīng)用可以有自己的類(lèi)體系,store、view、Model等元素。整個(gè)構(gòu)成一個(gè)所謂的:app。app.js是整個(gè)應(yīng)用的入口,用來(lái)初始化Ext.Application,當(dāng)然,你可以不叫app.js,比如叫:aipapa.js,都是可以滴??!但是里面是干這個(gè)事情的。。。
/** * 設(shè)置Extjs的動(dòng)態(tài)加載路徑 */ Ext.Loader.setConfig({ enabled: true, paths: { "Ext": "app/vendor/extjs/6.2.0", "Ext.ux": "app/vendor/extjs/6.2.0/ux" } }); /** * 是否開(kāi)啟url緩存,就是xxx.com?_dc=123123123123類(lèi)似這種 */ Ext.Ajax.disableCaching = false; /** * 初始化工具提示 */ Ext.QuickTips.init(); Ext.application({ name: "luter",//這個(gè)應(yīng)用叫啥,其實(shí)就是目錄名字 /** * 你把這個(gè)應(yīng)用放哪個(gè)目錄下了,控制器啊store啊view啥的,在哪里? * 以后定義一個(gè)叫Ext.define("luter.model.Car",{})的時(shí)候,其實(shí)就是指向了js文件:app/luter/model/Car.js * requiere就會(huì)動(dòng)態(tài) ajax load這個(gè)js下來(lái) */ appFolder: "app/luter", init: function () {//先初始化 console.log("init") }, launch: function () {//發(fā)射! console.log("launch") } });
最后,在入口html中記得引入這個(gè)文件。不出意外的話預(yù)覽app.html,console里應(yīng)該能看到點(diǎn)信息了,當(dāng)然,依然沒(méi)啥UI效果....接下來(lái)就創(chuàng)建view
開(kāi)始創(chuàng)建主view主view基礎(chǔ)是一個(gè)viewport,采用Border布局,頭部header+底部footer+左側(cè)導(dǎo)航樹(shù)+中間tab頁(yè)內(nèi)容切換。為了方便管理,主view統(tǒng)一放在main目錄下,主視窗: app/luter/view/main/viewport.js
/** * 主視圖占滿全屏是個(gè)viewport */ Ext.define("luter.view.main.ViewPort", { extend: "Ext.Viewport", alias: "widget.viewport",//別名,與xtype對(duì)應(yīng) layout: "border",//東南西北中布局,邊界嘛 stores: [], requires: [], initComponent: function () { var me = this; Ext.apply(me, { items: [{ region: "north", height: 40, title: "北方", xtype: "panel" }, { region: "west", xtype: "panel", title: "西方", width: 200 }, { region: "center", title: "中間", xtype: "panel" }, { region: "south", xtype: "panel", title: "南方", height: 40 }] }); me.callParent(arguments); } });建立主控制器:app/luter/controller/MainController.js
Ext.define("luter.controller.MainController", { extend: "Ext.app.Controller", views: ["main.ViewPort"],//默認(rèn)views會(huì)尋找項(xiàng)目目錄下的view目錄,也就是會(huì)掃描到app/luter/view了,所以直接下下級(jí)路徑即可。 stores: [], init: function (application) { var me = this; this.control({ "viewport": {//監(jiān)聽(tīng)viewport的初始化事件,可以做點(diǎn)其他事情在這里,如有必要,記得viewport定義里的alias么? "beforerender": function () { console.log("viewport begin render at:" + new Date()); }, "afterrender": function () { console.log("viewport render finished at:" + new Date()); }, } }); } });
控制器有了,視圖有了,接下來(lái)讓程序顯示這個(gè)UI,修改app.js
修改app入口: app/luter/app.js/** * 設(shè)置Extjs的動(dòng)態(tài)加載路徑 */ Ext.Loader.setConfig({ enabled: true, paths: { "Ext": "app/vendor/extjs/6.0.0", "Ext.ux": "app/vendor/extjs/6.0.0/ux" } }); /** * 是否開(kāi)啟url緩存,就是xxx.com?_dc=123123123123類(lèi)似這種 */ Ext.Ajax.disableCaching = false; /** * 初始化工具提示 */ Ext.QuickTips.init(); var luterapp;//定義一個(gè)全局app對(duì)象,便于后續(xù)使用 Ext.application({ name: "luter",//這個(gè)應(yīng)用叫啥,其實(shí)就是目錄名字 /** * 你把這個(gè)應(yīng)用放哪個(gè)目錄下了,控制器啊store啊view啥的,在哪里? * 以后定義一個(gè)叫Ext.define("luter.model.Car",{})的時(shí)候,其實(shí)就是指向了js文件:app/luter/model/Car.js * requiere就會(huì)動(dòng)態(tài) ajax load這個(gè)js下來(lái) */ appFolder: "app/luter", init: function () {//先初始化 console.log("init") }, launch: function () {//發(fā)射! console.log("launch") luterapp = this; this.loadModule({ moduleId: "MainController" }); var module = this.getController("MainController");//加載這個(gè)控制器 var viewName = module.views[0];//獲取到這個(gè)控制器里的第一個(gè)view名字 var view = module.getView(viewName);//獲取到這個(gè)view,本質(zhì)上就是加載js文件 view.create();//創(chuàng)建這個(gè)view }, /** * 動(dòng)態(tài)加載控制器 * @param config * @returns {boolean} */ loadModule: function (config) { if (!Ext.ClassManager.isCreated(config.moduleId)) { console.log("controller:" + config.moduleId + " is not load ,now load in....."); try { var module = luterapp.getController(config.moduleId); } catch (error) { showFailMesg({ msg: ":<> O! No:load module fail,the module object is null." + "
maybe :the module is Not available now." + "Error: " + error }); return false; } finally { } } } });
這里面用到了一個(gè)showFailMesg的函數(shù),這種彈出提示框的東西,可以做成通用的函數(shù)放在utils里,后續(xù)這個(gè)工具類(lèi)會(huì)逐漸完善。
如下:
/** * 操作成功提示 */ function showSucMesg(config) { Ext.Msg.show({ title: "成功", msg: config.msg || "", width: 400, buttons: Ext.Msg.OK, icon: Ext.MessageBox.INFO, fn: config.fn || "" }); } /** * 操作失敗提示 */ function showFailMesg(config) { Ext.Msg.show({ title: config.title || "失敗", msg: config.msg || "", width: 450, buttons: Ext.Msg.OK, icon: Ext.MessageBox.ERROR, fn: config.fn || "" }); }
當(dāng)然,這個(gè)js也需要在入口html引入,在app.js之前引入。如下:
修改入口html: app/app.htmlEXTJS6.2.0MVC