Project Name: pureMVC Utility - WidgetsConsole
Version: 1.0.0
Project Owner: Erin Lin
Description: An utility is under pureMVC Multicore that has Flex only and AS3 two versions.
Demo: WidgetsConsole Live Demo with source code
Demo source code
Download: WidgetsConsole Open Source Project Home
pureMVC website: http://puremvc.org/
沒想到我第一個 google code open source project 就獻給 pureMVC 了...
套用 pureMVC 到 Flex 專案第一個遇到的問題就是 view components 的控制,Flex 專案的 view 總類太多:有 Modules, UIComponent, external swf and pop-up view...etc. 整個專案作下來光 view 就可能換上幾十個頁面,先前分享了運用 StateMachine 來處理 view 的轉換,中大型專案作下來 code 的複雜度也是非常可觀。我在今年二月分享了 [Flex] pureMVC MultiCore with Modules 就開始著手將其概念包裝成 pureMVC 的工具包,使用到目前為止整個架構還是挺完善,所以在這邊與大家分享。
WdigetConsole 顧名思義是「 相同目的 views 組合 = Widget 」 的中央控制中心,將程式內加入 WidgetsConsole 的 widget 統一控管,最終只需要 sendNotification 就可以達到 view 的新增跟刪除(因為我是懶人工具的愛好者,懶人工具的定義就是以最低的限度達到所需要的效果,所以這個工具包的自由度很高!)
以下是簡單講解 WidgetsConsole 是什麼:
Widget 的定義: View component(s) + WidgetMediator + WidgetCommand
實作的 WidgetCommand:SimpleCommand 會掌控相關 views, proxies, commands 的註冊與移除。你可以發現上次在 pureMVC + StateMachine 文章中,Erin 建議將一個 view 的相關 Mediators, Proxies , Commands 都用一個 Command 來控制建立與刪除,其重點就是"只"讓一個 Command 掌握一個 views 組合的所有細節。
Interfaces: 想要自動化,介面是不可缺少的
- IWidgetShell:所有放置 Widget 的 DisplayObjectContainder 都需要實作。
- IWidget:view component or modules 只要需要被中央控管的 views 都要實作 IWidget
- IWidgetInfo:定義傳遞的 Value Object 介面
IWidgetShell 的實作
可以 extends 任何的 DisplayObjectContainder Class 來實作 IWidgetShell 介面,當然也可以參考 Live Demo 內的 AssignShell 寫法製作。如果你很在意巢狀容器的話,請避免使用 DisplayObjectContainder Class 來實作 IWidgetShell 介面。
WidgetCommand:SimpleCommand
寫法跟一般寫 Command 沒兩樣,差別在 execute 中只處理 WidgetsConsole.CREATE_WIDGET and WidgetsConsole.DESTROY_WIDGET。
- WidgetsConsole.CREATE_WIDGET:處理所有相關 View, mediator, proxies 的註冊,統一在此處理 view component 的 WidgetsConsole.ADD_WIDGET_TO_SHELL
sendNotification(
WidgetsConsole.ADD_WIDGET_TO_SHELL,
widget:IWidget,
ShellName:String
); - WidgetsConsole.DESTROY_WIDGET:處理所有相關 View, mediator, proxies 的刪除
需要在此處理 view component 的 WidgetsConsole.REMOVE_WIDGET_FROM_SHELL
sendNotification(
WidgetsConsole.REMOVE_WIDGET_FROM_SHELL,
widget:IWidget,
ShellName:String
);
How to Inject WidgetsConsole?
inject 函式的命名寫法參考自 pureMVC Utility - StateMachine
var wc:WidgetsConsole = new WidgetsConsole();
wc.inject( this.multitonKey );
wc.registerWidget( widgetName:String, command:Class );
//在這邊將做好的 WidgetCommand 註冊
wc.registerShell(name:String, shell:IWidgetShell);
//註冊 shell,由於 shell 是一個 IWidgetShell 實體,所以在實體被移除前一定要執行 removeShell
Widget 的呼叫:
sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( widgetName:String , mediatorName:String , targetShellName:String , moduleURL:String = null, attachment:Object = null )
);
這邊的 moduleURL:String 欄位請自由運用,在 WidgetCommand 內可以藉由 IWidgetInfo.getURL() 取得,由於一開始 Erin 就是針對 Flex 開發出這個工具包,所以 IWidgetInfo 並沒有分版本;AS3 版本只是將 Module 相關拿掉而已。
*Edit:10.26,2009 筆誤... moduleURL:String 寫成 targetShellName:String...
LazyWidget 的呼叫:懶人 widget,WidgetMediator and WidgetCommand 已由 WidgetsConsole 提供
只有 ViewUI 的 Widget,單純展示畫面,多為測試用。 inject WidgetsConsole 的時候 registerLazyWidget(),才可以使用。
sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( WidgetsConsole.LAZY_WIDGET , mediatorName:String , targetShellName:String , moduleURL:String =null, viewUIInstance:IWidget )
);
//*Edit:10.26,2009 筆誤... moduleURL:String 寫成 targetShellName:String...
//attachment 欄位直接帶入 IWidget
Widget 的刪除
//刪除全部 Widgets
sendNotification(WidgetsConsole.DESTROY_ALL_WIDGETS);
//刪除指定 shell 內所有的 Widgets
sendNotification(WidgetsConsole.DESTROY_WIDGETS_BY_SHELL, shellName:String );
sendNotification(WidgetsConsole.DESTROY_WIDGET, mediatorName:String );
//刪除特定 Widget
Module 專區 - Flex only version
ModuleWidget 的呼叫:外部 ModuleWidget 共用,WidgetMediator and WidgetCommand 已由 WidgetsConsole 提供
需要在 inject WidgetsConsole 的時候順便 registerModuleWidget(),才可以使用。
sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( WidgetsConsole.MODULE_WIDGET , mediatorName:String , targetShellName:String , moduleURL:String , attachment:Object = null )
);
//WidgetsConsole 會將 attachment:Object 送到 Module.data,所以需要直接寄到 Module 的參數可以利用 attachment 傳送。
Module 專用的 broadcast to Global Notification:WidgetsConsole.MODULE_SENDER
發出通知後會自動轉變成 「WidgetsConsole.BROADCASTING 」到 System facade ,也會順便轉發出 「WidgetsConsole.MODULE_RECEIVER」 送進"其他"的 ModuleWidget(自己發送的 Notification 就不會接收),所以 WidgetsConsole.BROADCASTING 請謹慎使用...
sendNotification( WidgetsConsole.MODULE_SENDER , body:Object , type:String );
//body is an Object...可以放任何你想要傳出去的物件~~萬物皆物件啊!
Module 外部資料接收器:WidgetsConsole.MODULE_RECEIVER
override public function listNotificationInterests():Array
{
return [
WidgetsConsole.MODULE_RECEIVER
];
}
override public function handleNotification(notification:INotification):void
{
//就是處理你要的東西
}
Module remove Notification:WidgetsConsole.MODULE_REMOVE
不管是由 Module 發出 WidgetsConsole.MODULE_REMOVE,又或者從 System facade 發出 WidgetsConsole.DESTROY_WIDGET 都會送出 WidgetsConsole.MODULE_REMOVE 讓 Module facade 收聽,所以請記得在 Module's ApplicationFacade 內註冊 WidgetsConsole.MODULE_REMOVE Command,並將此 Module 在移除時需要清除的東西寫在此 Command 內。
sendNotification( WidgetsConsole.MODULE_REMOVE );
// remove self
其實目前 mx.modules.ModuleManager 有要命的 memory leak bug...建議現階段還是少用 Module 比較安全。這也是我使用 RSL(Runtime Shared Library) 來處理專案的主要原因,Module 只用來實作非主要的 view componet。
想要取得你所載入的 Module's ModuleInfo 去執行 unload() 的話,請利用 ModuleManager.getModule(url):IModuleInfo 來取得,關於這點我沒有在 WidgetsConsole 內處理的原因是:不管 ModuleInfo 有沒有執行 unload,其 ModuleInfo 還是會剩下一個實體不被回收,可能的原因是 ModuleManager 內的 inner class ModuleManagerImpl 有個 moduleList 在 ModuleInfo.unload 的時候並沒有順便清掉其 reference,當然也可能還有其他的因素。既然有沒有 unload 都沒差別那就不需要特別處理它了...=)
還能說什麼呢...這真的太有大愛了!
ReplyDelete我在live demo with source code連結找不到source code呀~
ReplyDelete有阿....滑鼠按右鍵不是有 view source...
ReplyDelete報告^^
ReplyDelete沒有看到view source捏~~~
看情況好像被 Hinet 的垃圾廣告 JS 擋起來了....等我有空的時候再去查解法來解決~~- -....
ReplyDelete阿咧...今天看的時候 online Demo 的 View source 又可以開了...= =
ReplyDelete