Flex Viewer 开发教程(6)Widget与共享数据

来源:互联网 发布:html书籍 知乎 编辑:程序博客网 时间:2024/03/29 07:38

Widget与共享数据

 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)) + " ";

                                    }

                                    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>

  •  在Widget的creationComplete事件的响应方法中,通过ViewerContainer对DATA_SENT和DATA_NEW_PUBLISHED事件进行监听。
  • DATA_SENT 事件的响应方法,DataManager在两种情况下派发DATA_SENT事件,一是获取所有的共享数据, 二是通过key获取共享数据。所以在此实现方法中要对这两种数据区别对待,如果返回的数据是Hashtable类型,则返回的是所有的共享数据,否则返回的是根据key获取的共享数据。
  •   DATA_NEW_PUBLISHED事件的响应方法,获取的是最新被共享的数据。DataManager会把最新被共享的数据分发出来(我们已经对 DataManager的addData()方法进行了修改,以期达到这个目的)。
  • 调用addShareData()方法共享数据。
  •  调用fetchShareDataByKey()方法通过key获取共享数据。
  • 调用fetchShareData()方法获取所有的共享数据。

HelloDataManagerWidget运行时如下图所示:

\

a)    点击Fetch All按钮:获取所有的共享数据。

数据共享机制为业务系统开发提供了很大的方便,比如当一个Widget第 一次打开时,需要之前的一些数据进行运算,此时即可通过共享机制实现。