Flex Viewer 開發教程(6)Widget與共享資料

gispace發表於2011-05-15

 

Flex Viewer通過DataManager提供資料共享服務,各個模組可通過事件進行資料共享和資料獲取。DataManager負責將共享資料以key-value的形式儲存於記憶體,並隨時準備接收和派發共享資料。先來分析一下DataManager的程式碼:

public class DataManager extends EventDispatcher{

 

    private var dataTable:Hashtable;

 

    public function DataManager(){

super();

dataTable=new Hashtable();

ViewerContainer.addEventListener(AppEvent.CONFIG_LOADED, config);

        //this is a example to setup the listner to get the type of data

 the Data

        //Manager is interested in.

       ViewerContainer.addEventListener(AppEvent.DATA_FETCH_ALL,

fetchAllData);

       ViewerContainer.addEventListener(AppEvent.DATA_PUBLISH,

addData);

        ViewerContainer.addEventListener(AppEvent.DATA_FETCH,

fetchData);

    }

 

private function config(event:AppEvent):void{

}

 

    private function fetchAllData(event:AppEvent):void{

       ViewerContainer.dispatchEvent(new AppEvent(AppEvent.DATA_SENT,

 dataTable));

    }

 

    private function fetchData(event:AppEvent):void{

       var key:String=event.data.key as String;

       var data:Object={key: key, collection: dataTable.find(key)};

       ViewerContainer.dispatchEvent(new

AppEvent(AppEvent.DATA_SENT, data));

    }

 

    private function addData(event:AppEvent):void{

       var key:String=event.data.key;

       if (key){

           var dataCollection:Object=event.data.collection;

           if (dataTable.containsKey(key)){

              dataTable.remove(key);

           }

           dataTable.add(key, dataCollection);

           //var data:Object={key: key, data: dataTable};

              // change by ropp to just send new published data

              var data:Object={key: key, data: dataCollection};

           ViewerContainer.dispatchEvent(new

AppEvent(AppEvent.DATA_NEW_PUBLISHED, data));

       }

    }

}

    雜湊表例項,用來以key-value的形式儲存共享資料;

    監聽CONFIG_LOADED事件;

    監聽DATA_FETCH_ALL(獲取所有共享資料)事件;

    監聽DATA_PUBLISH(釋出共享資料)事件;

    監聽DATA_FETCH(根據key獲取共享資料)事件;

    DATA_FETCH_ALL事件響應方法;

    DATA_FETCH事件響應方法,根據key返回對應的共享資料;

    DATA_PUBLISH事件響應方法,將釋出的共享資料儲存,並將最新的共享資料分發出去(DATA_NEW_PUBLISHED事件)。此處原始碼有一點小問題,修改見註釋。

再來看一下BaseWidget對共享資料的支援,BaseWidget有如下程式碼:

/**

 * Add information from a widget to the DataManager so that it can be shared

 between widgets.

 * @param key the widget name

 * @param arrayCollection the list of object in infoData structure.

 */

public function addSharedData(key:String,

arrayCollection:ArrayCollection):void{

    var data:Object = {

                key: key,

                collection: arrayCollection

    };

ViewerContainer.dispatchEvent(new AppEvent(AppEvent.DATA_PUBLISH,

 data));

}

/**

 * Fetch shared data from DataManager.

 */

public function fetchSharedData():void{

ViewerContainer.dispatchEvent(new

AppEvent(AppEvent.DATA_FETCH_ALL));

}

/**

* Fetch share data from DataManager by key

* @param key

*/

public function fetchShareDataByKey(key:String):void{③新新增方法

ViewerContainer.dispatchEvent(new

AppEvent(AppEvent.DATA_FETCH, {key:key}));

}

    addShareData()方法用來向DataManager釋出共享資料;

    fetchShareData()方法用來向DataManager請求所有的共享資料;

    fetchShareDataByKey()方法在BaseWidget中未提供,我們不妨把這個方法加上去,用來向DataManager請求以key儲存的共享資料。

下面實現一個HelloDataManagerWidget來說明如何釋出和獲取共享資料,程式碼如下:

<?xml version="1.0" encoding="utf-8"?>

<viewer:BaseWidget 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:viewer="com.esri.viewer.*"

                 creationComplete="init()">

    <fx:Script>

       <![CDATA[

           import com.esri.viewer.AppEvent;

           import com.esri.viewer.ViewerContainer;

           import com.esri.viewer.utils.Hashtable;

           import mx.collections.ArrayCollection;

 

           private function init():void{

              ViewerContainer.addEventListener(AppEvent.DATA_SENT,

 dataSentHandler);

ViewerContainer.addEventListener(AppEvent.DATA_NEW_PUBL

ISHED, dataNewPublishedHandler);

           }

 

           private function dataSentHandler(event:AppEvent):void{

              if (event.data is Hashtable){

                  var keyValue:String="";

                  var table:Hashtable=Hashtable(event.data);

                  var keySet:Array=table.getKeySet();

                  for each (var key:String in keySet){

                     keyValue+="key: " + key + "; value: " +

String(table.find(key)) + "/n";

                  }

                  allValue.text=keyValue;

              }

              else if (event.data.collection)

                  fValue.text=event.data.collection[0];

           }

 

           private function

dataNewPublishedHandler(event:AppEvent):void{

              var data:Object=event.data;

              var key:String=data.key;

              var value:String=data.data[0];

              this.nKey.text=key;

              this.nValue.text=value;

             }

 

           private function shareData():void{

              this.addSharedData(key.text, new

ArrayCollection([value.text]));

           }

 

           private function fetchByKey():void{

              this.fetchShareDataByKey(fKey.text);

           }

 

           private function fetchAll():void{

              this.fetchSharedData();

           }

       ]]>

    </fx:Script>

    <viewer:WidgetTemplate width="500" height="300">

       <s:VGroup width="100%" height="100%">

           <s:HGroup width="100%" verticalAlign="middle">

              <s:Label text="Key"/>

              <s:TextInput id="key"/>

              <s:Label text="Value"/>

              <s:TextInput id="value"/>

              <s:Button label="Share" click="shareData()"/>

           </s:HGroup>

           <s:HGroup width="100%" verticalAlign="middle">

              <s:Label text="New Share Data"/>

              <s:Label text="Key"/>

              <s:TextInput id="nKey"/>

              <s:Label text="Value"/>

              <s:TextInput id="nValue"/>

           </s:HGroup>

           <s:HGroup width="100%" verticalAlign="middle">

              <s:Label text="Key"/>

              <s:TextInput id="fKey"/>

              <s:Button label="Fetch by Key" click="fetchByKey()"/>

              <s:Label text="Value"/>

              <s:TextInput id="fValue"/>

           </s:HGroup>

           <s:VGroup width="100%" height="100%"

                    verticalAlign="middle" horizontalAlign="center">

              <s:Button label="Fetch All" click="fetchAll()"/>

              <s:TextArea id="allValue" width="100%" height="100%"/>

           </s:VGroup>

       </s:VGroup>

    </viewer:WidgetTemplate>

</viewer:BaseWidget>

    WidgetcreationComplete事件的響應方法中,通過ViewerContainerDATA_SENTDATA_NEW_PUBLISHED事件進行監聽。

    DATA_SENT事件的響應方法,DataManager在兩種情況下派發DATA_SENT事件,一是獲取所有的共享資料,二是通過key獲取共享資料。所以在此實現方法中要對這兩種資料區別對待,如果返回的資料是Hashtable型別,則返回的是所有的共享資料,否則返回的是根據key獲取的共享資料。

    DATA_NEW_PUBLISHED事件的響應方法,獲取的是最新被共享的資料。DataManager會把最新被共享的資料分發出來(我們已經對DataManageraddData()方法進行了修改,以期達到這個目的)。

    呼叫addShareData()方法共享資料。

    呼叫fetchShareDataByKey()方法通過key獲取共享資料。

    呼叫fetchShareData()方法獲取所有的共享資料。

HelloDataManagerWidget執行時如下圖所示:

 

u  點選Share按鈕:共享key-value資料,同時最新的共享資料會在New Share Data中顯示出來;

u  點選Fetch by Key按鈕:根據key獲取value

u  點選Fetch All按鈕:獲取所有的共享資料。

資料共享機制為業務系統開發提供了很大的方便,比如當一個Widget第一次開啟時,需要之前的一些資料進行運算,此時即可通過共享機制實現。

 

相關文章