天天看點

一步一步使用Ext JS MVC與Asp.Net MVC 3開發簡單的CMS背景管理系統之建立Viewport(2)...

現在要考慮的是如何加載标簽頁内的内容。雖然标簽頁預設是延遲渲染的(deferredRender值預設為true),但是它會預加載所有的類,因而當類檔案很多的時候,加載時間就是一大問題了。這個,也可通過SDK打包的方式解決,不過在設計階段還是要考慮的。另一種好的解決方法是,隻使用标簽頁的标簽,而不使用其主體加載内容,另外使用一個容器,内部使用CardLayout作為布局,類似書中最後一章的示例實作面闆内容的加載和切換。

在這裡,将展示另一種方式,就是在标簽頁激活時才去加載内容頁。因而,這需要監聽标簽頁的activate事件。這樣,問題又來了,是在标簽頁面闆監聽activate事件,還是在每個獨立的标簽頁内監聽activate事件。如果是在标簽頁面闆内監聽,就要判斷目前标簽頁的哪一個,是否需要加載内容,因為文章的詳細資訊頁也是标簽頁,因而這些都需要做判斷。這個,筆者因為雖然寫法簡化了,但是要做的判斷實在太多,不算太好的方法。而在具體标簽頁内監聽,則不需要任何判斷,而且可以設定事件為一次性性事件,也就是在監聽時設定事件的single配置項為true,這樣監聽事件在執行一次後就會自動删除,不再監聽了。

要在Viewport内為各标簽頁添加activate事件,就不太符合MVC要求了。是的,這個在頂部實作退出按鈕的時候已經違反要求了。因而都需要做出修改。不過,筆者也曾思前想後的考慮過,開發應用程式,是否就要這麼刻闆呢?尤其是像退出這樣簡單的操作,而且對于Javascript這樣靈活的語言。這個,如果探讨起來,就和語言之争一樣沒什麼意義了,大家還是根據自己習慣,靈活掌握吧。

為了實作标簽頁的MVC化,先在view目錄下建立一個名稱為MainPanel.js的檔案,在檔案裡定義一個擴充于标簽面闆的控件,基本代碼如下:

Ext.define('SimpleCMS.view.MainPanel',{

extend : 'Ext.tab.Panel',

alias: 'widget.mainpanel',

flex: 1,

initComponent: function(){

var me = this;

me.callParent(arguments);

}

});

使用配置項alias來為元件定義一個别名非常有必要,不然在Viewport就不能使用xtype來建立元件了,在這裡,别名是mainpanel。在initComponet方法内,将Viewport建立mainpanel執行個體的代碼複制過來,并修改如下:

me.items= [

{ title: "文章管理" , id :"contentPanel"},

{ title: "圖檔管理" , id : "picPanel"}

];

varroles = "." + SimpleCMS.Userinfo.Roles.join('.') + ".";

if(roles.indexOf(".系統管理者.") >= 0) {

me.items.push({ title: "使用者管理",id:"userPanel"});

}

因為是在元件内,是以将标簽頁加到items裡就行了。要注意,所有标簽頁都添加了id,其目的是為了友善在控制器中找到面闆,當然,這個使用其它方式擷取也行,隻是這樣的方式是最快最直接的。這個可根據項目具體情況再做決定。還要注意,添加使用者管理标簽頁時,用的是數組的push方法,而不是面闆的add方法了。

現在,在Controller目錄建立一個名稱為MainPanel.js的腳本檔案,用來定義主面闆的控制,基本定義代碼如下:

Ext.define('SimpleCMS.controller.MainPanel',{

extend: 'Ext.app.Controller',

init: function () {

}

});

因為控制器裡不需要引用元件,也不需要模型和Store,因而沒有定義refs、store和model配置項,隻是定義了init方法。在init方法内,需要使用控制器的control方法來擷取主面闆内的标簽頁,并為其添加activate事件,具體代碼如下:

this.control({

'#contentPanel': {

activate: {

single: true,

fn : function (panel) {

console.log(panel);

}

}

},

'#picPanel': {

activate: {

single: true,

fn: function (panel) {

console.log(panel);

}

}

},

'#userPanel': {

activate: {

single: true,

fn: function (panel) {

console.log(panel);

}

}

}

}

代碼中,對象中的關鍵字就是選擇器,用來查找元件用的,在這裡要使用id來查找,因而在元件id前面要添加“#”符号,表示使用id查找元件。在元件内,綁定了activate事件,事件中,single配置項說明該事件隻執行一次,配置項fn則是事件的回調函數,目前隻是簡單的顯示傳回的面闆對象。

在這裡,沒有使用權限添加使用者面闆的原因是,如果找不到元件,它不會做任何處理,因而不使用權限添加也沒問題的,不像可視元件内,如果不限制,就會顯示出來。在這裡,一般都會擔心,這會不會造成安全問題?被利用來實作無權限的操作,這個其實不用擔心,就算它能看到顯示的元件,但是我背景通過權限控制傳回的資料,它沒有權限,是看不到任何資料的,也不能對沒權限的資料進行任何操作。

控制器定義好以後,切換會Viewport.js,先添加一個requires配置項,讓其自動加載MainPanel,代碼如下:

requires:['SimpleCMS.view.MainPanel'],

這句是必須的,不然會找不到元件。

然後将之前添加mainpanel的代碼全部删除,在items内原來添加主面闆的位置添加以下代碼來添加主面闆視圖:

{xtype: "mainpanel", id: "mainPanel" },

在這裡,也加了一個id,也是為了友善以後使用選擇器查找元件。

因為要加載主面闆的控制器,是以要在首頁Index.cshtml使用application方法建立應用時添加controllers配置項,代碼如下:

controllers:["MainPanel"]

這樣,就可自動加載主面闆的控制器了。

現在,在浏覽器中打開首頁,使用test使用者登入,會看到界面和之前看到的沒有差別。如果打開了Firebug,會看到以下顯示:

[試用版]Ext.panel.Panel { id="contentPanel", title="文章管理"}

這說明activate事件已被觸發了,不相信?可以在activate事件内添加别的東西來做個驗證。

單擊一下圖檔管理,會看到Firebug裡又多了以下資訊:

[試用版]Ext.panel.Panel { id="picPanel", title="圖檔管理"}

說明圖檔管理面闆的activate也被觸發了。

現在再切換回文章管理,會發現不再有提示資訊了,原因就是activate事件設定了配置項single為true,它隻會執行一次。

好了,Viewport到此就已經完成了。現在的重點是如何在主面闆控制器内控制内容的加載了。

源代碼下載下傳位址:http://download.csdn.net/detail/tianxiaode/4590190

繼續閱讀