本文是發表在InsideRIA上Robotlegs 系列文章的第一部分。在接下來的幾個星期裏,本系列的其它文章將詳細介紹Robotlegs 的基礎概念以及一些高級概念(涉及到如何使用第三方實用程序、庫)。
Roboglegs是什麼?
簡單地說,Robotlegs 提供了一種機制,用於應用程序中的對象之間進行通信。比如對象A需要和對象B進行通信,在Robotlegs 的幫助下對象A甚至不需要知道對象B是否存在。那麼它們如何進行通信呢?最簡單的答案是通過事件,在Flash中,原生的事件系統爲這種通信方式帶來了很多便利,你不可避免地每天都要使用事件。位於顯示列表上的對象通過事件進行通信,事件冒泡允許對象從其它顯示對象接收消息,但是如果對象並不位於顯示對象列表上,該如何進行通信呢?這正是像Robotlegs 這樣的框架能爲你提供幫助的地方。
就其核心來講,Robotlegs 是一系列功能模塊和接口的集合。在應用程序中,這些功能模塊和接口用於簡化通信任務,減少重複代碼,並且管理依賴注入。除此以外,Robotlegs 提供了一個輕量級的MVC+S(Model、View、Controller和Service)實現,作爲應用開發的起點。如果你有使用PureMVC框架的經驗,你將很快熟悉如何在Robotlegs 中使用Mediators 和Commands;如果沒有,也不必擔心,我們將馬上深入的介紹這些類。
本文將通過一個簡單的“Hello World”,對Robotlegs 進行概述。看完這個例子後,你可能會想,“嗯,我能毫無困難地在單個MXML文件中完成這一切。”但這只是一個很簡單的例子,切記,在大型項目中是不能這麼做的。這裏並不打算對Robotlegs 進行詳細的解剖,但是希望它足以激發你的興趣。在文末我已經提供了一些資源方便你對Robotlegs 進行進一步探索。下面,還是讓我們來看一些代碼。
Robotlegs MVC+S應用的基本結構
一個典型的Robotlegs MVC+S應用由以下幾部分構成:
Context Context負責初始化依賴注入以及各種Robotlegs 需要使用的核心功能。
Mediators Mediators負責應用中視圖組件與應用中其它對象之間的通信。
Commands Commands代表應用所能執行的單個行爲。Commands的典型功能是響應用戶的行爲,比如鼠標事件,但是並不僅限於此。
Models Models用於存儲數據,描繪應用的當前狀態。
Service Service是應用與外部交互的門戶。
下面從Context開始,讓我們更深入的探究一下Context和Mediators。Context是整個應用的中心,它提供了一個事件總線,用於應用的其它部分對象之間進行通信。只有在應用啓動和初始化時,你才需要處理Context。其它時候你不用理會它,它自己啓動,完成自己的工作。[…] Context並不是一個單例對象,爲了適應模塊化應用的場景,應用可以有多個Context。在這裏我們並不打算研究應用的模塊化問題,但是鑑於模塊化應用是一個很強大的工具,它將會是出現在未來文章中的一個主題。下面讓我們來看一個最基本的Context。
[HellowWorldContext.as]
- import org.robotlegs.mvcs.Context
- public class HelloWorldContext extends Context
- {
- override public function startup():void
- {
- //bootstrap here
- }
- }
[HelloWorld.mxml]
- <?xml version="1.0"?>
- <s:Application
- xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx"
- xmlns:local="*">
- <fx:Declarations>
- <local:HelloWorldContext contextView="{this}"/>
- </fx:Declarations>
- </s:Application>
Mediators居於視圖組件與應用的其它部分之間,簡單一點講,Mediators負責監聽事件。當用戶與視圖組件交互時或視圖組件以某種方式更新時,視圖組件會分發事件,這些事件必須被捕獲,並且分發到應用的其它部分。有可能是用戶點擊了一個保存按鈕,一些表單信息需要發送到服務器。Mediators監聽這些事件,當事件發生時,Mediators收集必要的信息,發送一個事件以便應用的其它部分能用這些數據來執行一些工作。另外,Mediators也監聽應用的其它部分分發的事件,如果從服務器接收到一些數據,在進行解析後,Service類會分發一個事件,Mediators是你監聽這個事件的地方,並且根據新的數據更新視圖組件。下面是一個將獲得中介的視圖:
[MessageView.mxml]
- <?xml version="1.0"?>
- <s:TextArea
- xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx">
- </s:TextArea>
[MessageViewMediator.as]
- import org.robotlegs.mvcs.Mediator;
- public class MessageViewMediator extends Mediator
- {
- [Inject]
- public var view:MessageView;
- override public function onRegister():void
- {
- trace("I am registered!");
- }
- }
當Mediator完全初始化之後,onRegister()方法爲你提供了一個插入點,這個時候注入已經完成,視圖組件也已經處於可用狀態,典型地你可以添加事件監聽器監聽視圖組件和應用分發的事件。典型地,在創建的每個Mediator中,你應該覆蓋這個方法。
現在你已經擁有一個視圖組件和Mediator了,它們需要在Context中進行註冊或者說映射。我們可以通過MediatorMap完成此操作,顧名思義,MediatorMap負責在Context中映射Mediator和對應的視圖組件。另外MediatorMap默認監聽contextView的“ADD_TO_STAGE”和”REMOVED_FROM_STAGE”事件,以便自動創建和銷燬視圖組件對應的Mediator。值得一提是,在圖形密集型的應用中,可能會有大量的顯示對象,自動創建Mediator可能會導致性能問題,雖然在一般的應用中,自動創建Mediator帶來了很多便利而且也很難影響性能。下面我們在HelloWorldContext中映射MessageView和MessageViewMediator。
- override public function startup():void
- {
- mediatorMap.mapView(MessageView, MessageViewMediator);
- }
[HellowWorld.mxml]
- <?xml version="1.0"?>
- <s:Application
- xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx"
- xmlns:local="*">
- <fx:Declarations>
- <local:HelloWorldContext contextView="{this}"/>
- </fx:Declarations>
- <local:MessageView top="40" width="100%" height="100%"/>
- </s:Application>
Robotlegs框架圖