標籤:style blog class c code java
開發環境
eclipse(indigo) ExtJS4.0
開發目標
使用store、model和controller建立菜單樹
開發步驟
之前我們已經建立了一個MVC的項目架構。現在要做的就是在這個基礎上給項目添加一個左側菜單。
首先,在/app/中定義一個菜單視圖類TreeMenu.js:
Ext.define(‘demo.view.TreeMenu‘, { extend: ‘Ext.tree.Panel‘, alias: ‘widget.treemenu‘, title: ‘系統功能表‘, margins: 5});
我們定義的TreeMenu類繼承了treepanel類,用於實現系統功能表。
alias表示類的別名。在我們需要使用這個類建立對象時,我們可以直接使用“xtype: ‘treemenu’”這樣的方式。
然後我們在viewport中引用這個類:
Ext.define(‘demo.view.Viewport‘, { extend: ‘Ext.container.Viewport‘, layout: ‘border‘, requires: [ ‘demo.view.TreeMenu‘ ], items: [{ region: ‘north‘, height: 65, html: ‘<div style="text-align:center; font-size:36px;">ExtJS MVC 示範</div>‘ },{ region: ‘west‘, width: 225, xtype: ‘treemenu‘ },{ region: ‘center‘ }]});
在viewport通過requires添加了對TreeMenu類的引用。“demo.view.TreeMenu”表示在命名空間demo下的view目錄下的TreeMenu類。
之後使用xtype:’treemenu’建立了TreeMenu類的對象。
如下是示範效果:
我們現在只是建立了一個菜單樹的面板。現在需要在面板中添加菜單樹。
菜單樹的資料從menu.json中擷取:
而後使用store和model來擷取資料。通常store決定擷取資料的方式,model決定擷取那些資料及資料樣式(有時也會將擷取資料的proxy置於model中),使用時通過store調用model。
這裡是我們的model類MenuModel.js:
Ext.define(‘demo.model.MenuModel‘, { extend: ‘Ext.data.Model‘, fields: [‘text‘, ‘leaf‘]});
我們的store類MenuStore.js:
Ext.define("demo.store.MenuStore",{ extend:‘Ext.data.TreeStore‘, model: ‘demo.model.MenuModel‘, autoLoad: true, proxy: { type:‘ajax‘, url:‘menu.json‘, reader: { type: ‘json‘ } }});
這裡有一個屬性要說明下:autoLoad,true表示store建立完成後自動載入資料。
現在我們有資料了,也設定了擷取資料的方式,接下來要做的就是通知應用來取資料。這裡就需要controller了。controller是粘合應用的膠水。
如下是MenuController類:
Ext.define(‘demo.controller.MenuController‘, { extend: ‘Ext.app.Controller‘, stores: [‘MenuStore‘], model: [‘MenuModel‘], views: [‘TreeMenu‘]});
如果之前有看過《ExtJS MVC結構》一文的話(建議看一下,官方文檔說的比較詳細透徹而且有比較好的執行個體),可以知道在controller中引用store後,就為store建立了一個同名的storeid,我們可以在view中直接使用這個storeid。以下是修改過的TreeMenu類:
Ext.define(‘demo.view.TreeMenu‘, { extend: ‘Ext.tree.Panel‘, alias: ‘widget.treemenu‘, title: ‘系統功能表‘, margins: 5, initComponent: function() { Ext.apply(this, { store: ‘MenuStore‘, rootVisible: false }); this.callParent(); }});
修改後,我們使用apply函數為treemenu類添加屬性。這個過程是寫在了initComponent函數中。initComponent函數是在定義子類時用作構造器使用。顧名思義,initComponent函數在類建立時被首先調用,並且會向上一直追溯到祖先類。因此在initComponent函數中必須有callParent的調用。
不過也有人是這樣做的:
Ext.define(‘demo.view.TreeMenu‘, { extend: ‘Ext.tree.Panel‘, alias: ‘widget.treemenu‘, title: ‘系統功能表‘, margins: 5, store: ‘MenuStore‘, rootVisible: false});
沒有使用apply函數,顯得比較簡潔。這樣子的做法我也試了一下,在家中測試沒有成功,在公司測試成功了一次。覺得不是很穩定的一個做法。原因還沒有深究,估計和js的運行順序有關。建議還是用apply函數。在官方的執行個體中也是多使用apply函數。
好了,這次的目標只差臨門一腳了。最後我們還要告訴app去找到controller,然後通過controller串起這個應用來,修改app.js:
Ext.application({ name: ‘demo‘, controllers:[‘MenuController‘], autoCreateViewport: true});
然後看下目前系統的檔案結構:
是運行結果: