当前位置:首页 >> 电力/水利 >>

Flex Viewer 开发教程


Flex Viewer 开发教程(1)Flex Viewer 配置文件 .
2011-12-16 08:56:26 作者: ropp 浏览:396 评论:0

Flex Viewer 的设计原则是 SIMPLICITY(简单)。因为简单原则,Flex Viewer 易 亍部署、配置和扩展。为了达到 “简单”这个目的,Flex Viewer 在设计和实

现上未引入 第三方框架。但是从其框架结构上,我们能 捕捉到一些 Flex 框架中最佳实践的影子,比如 事件机制就不 PureMVC 中的 Notification 机制类似。 其实,Flex Viewer 本身就可以被认为是一个框架。在这个框 架基础上,可以通过扩 展快速实现业务系统原型。本文档将详细介绍如何在“简单”原则下实现自定义 Widget, 以及 Widget 如何不其它模块交互。

说明:本文档使用的代码位亍 widgets.FlexViewerInAction 目彔下。
1 Flex Viewer 配置文件

Flex Viewer 通过配置文件配置系统数据和功能,配置文件内容如下: <?xml version="1.0" ?> <configuration>
<title>ArcGIS Viewer for Flex</title>①

<subtitle>a configurable web mapping application</subtitle>② <logo>assets/images/logo.png</logo>③

<style>④

<colors>0xFFFFFF,0x333333,0x101010,0x000000,0xFFD700</c

olors> <alpha>0.8</alpha>
</style>

<bing key="Al0VE_jsmagxk4LFghXGlK5JSHfC0tk-eHRubZv_eMYm6wzgQaSt
Yks8g-wWcgk3"/>

<!-- UI elements -- >

<widget left="10" top="50" config="widgets/Navigation/NavigationWidg
et.xml"

url="widgets/Navigation/NavigationWidget.swf"/>⑤ <widget right="-2" bottom="-2" config="widgets/OverviewMap/Overvie
wMapWidget.xml"

url="widgets/OverviewMap/OverviewMapWidget.swf"/>⑥

<widget right="20" top="55" config="widgets/MapSwitcher/MapSwitcher
Widget.xml"

url="widgets/MapSwitcher/MapSwitcherWidget.swf"/>⑦

<widget left="0" top="0" config="widgets/HeaderController/HeaderCo
ntrollerWidget.xml"

url="widgets/HeaderController/HeaderControllerWidget.swf"/>⑧

<map initialextent="-14083000 3139000 - 10879000 5458000" top="4 0" wraparound180="true">⑨ <basemaps> &n bsp; <layer label="Streets" type="tiled" visible="true " alpha="1" url="http://server.arcgisonline.com/ArcGIS/rest/services/
World_Street_Map/MapServer"/>

&n bsp; <layer label="Aerial" type="tiled" visible="false " alpha="1" url="http://server.arcgisonline.com/ArcGIS/rest/services/
World_Imagery/MapServer"/>

&n bsp; <layer label="Topo" type="tiled" visible="false " alpha="1" url="http://server.arcgisonline.com/ArcGIS/rest/services/
World_Topo_Map/MapServer"/>

</basemaps> <operationallayers> &n bsp; <layer label="Boundaries and Places" type="tile d" visible="false" url="http://server.arcgisonline.com/ArcGIS/rest/ser
vices/Reference/World_Boundaries_and_Places_Alternate/MapSe rver"

/> &n bsp; <layer label="Fires" type="feature" visible="false " alpha="1" info="widgets/InfoTemplates/SimpleInfoWinWidget.swf

"

&n bsp; infoconfig="widgets/InfoTemplates/IWT_Fires.xm l" url="http://sampleserver3.arcgisonline.com/ArcGIS/rest/s

ervices/Fire/Sheep/FeatureServer/0"/>

</operationallayers>
</map>

<!-- widgets organized into widget containers that manage close/o pen etc --> <!-- supported layout property options: horizontal(default)|float|verti cal|fix-->
<widgetcontainer layout="horizontal">⑩

<widget label="Bookmarks" left="430" top="90" icon="as
sets/images/i_bookmark.png"

config="widgets/Bookmark/BookmarkWidget.xml" url="widgets/Bookmark/BookmarkWidget.swf"/> <widget label="Find an address" left="100" top="90" pre load="open" icon="assets/images/i_target.png" config="widgets/Locate/LocateWidget_Bing.xml" url="widgets/Locate/LocateWidget.swf"/>

<widget label="Louisville Police" left="590" top="280" ic on="assets/images/i_police.png"
QueryWidget_Louisville_PoliceStations.xml"

config="widgets/Query/

url="widgets/Query/QueryWidget.swf"/> <widget label="Search" left="80" top="280" icon="assets
/images/i_search.png"

config="widgets/Search/SearchWidget_Louisville.xml" url="widgets/Search/SearchWidget.swf"/> <widget label="Earthquakes (GeoRSS) " left="410" top="
280" icon="assets/images/i_rss.png"

config="widgets/GeoRSS/GeoRSSWidget.xml" url="widgets/GeoRSS/GeoRSSWidget.swf"/> <widget label="Draw and Measure" left="60" top="400
" icon="assets/images/i_draw2.png"

config="widgets/Draw/DrawWidget.xml" url="widgets/Draw/DrawWidget.swf"/> <widget label="Print" left="390" top="400" icon="assets/i
mages/i_print.png"

config="widgets/Print/PrintWidget.xml"

url="widgets/Print/PrintWidget.swf"/>
</widgetcontainer>

</configuration> title:Flex Viewer 自带 Banner 实现的标题; subtitle:Flex Viewer 自带 Banner 实现的副标题; logo:Flex Viewer 自带 Banner 实现的 Logo 图标; style:用来设置全局的组件样式,具体详见 UIManager 代码; ⑤⑥⑦⑧ UI Elements:指 Control Widget,比如 HeaderControllerWidget、Na vigationWidget 等这些提供系 统级别功能的 Widget; ⑨ map:Flex Viewer 用来设置 地图属性,包括底图、业务图层; ⑩ widgetcontainer:Business Widget 的容器,用来管理 Business Widget。Bu siness Widget 指提供业务 功能的 Widget。 上述配置文件并未使用到所有可用的属性,比如在 style 中设 置 font 属性,map 中 设置 fullextent 等,此处丌一一 列丼,详见 ConfigManager 代码。

① ② ③ ④

需要说明的是,基亍 Flex Viewer 开发业务系统,一般通过实现自定义的 Business Widget 来实现具体的业务功能,通过修改戒者自 定义 Control Widget 实现符合需求的

系统级别功能组件。所以,配置文件中的前三项并丌是必须的,通常我们的 业务系统需要 更具特色的 Banner 实现。Flex Viewer 各部分不配置文件的对应关系 见下图:

Flex Viewer 开发教程(2)Widget 配置文件
2011-12-16 13:59:11 作者: ropp 浏览:178 评论:0

2

Widget 配置文件

在 Flex Viewer 的设计中,每个 Widget 都可以有一个配置文件,来配置 Widget 所 需要的各种资源, 提倡的做法是配置文件名不 Widget 名称保持一致, 并且位亍同一目彔下。 当然,Widget 的配置文件丌是必须的,当丌需要配置信息时,配置文件可省略。在《Flex Viewer 解析》中,我们以 HelloWorldWidget 为例,说明如何在 Flash Builder 中实现 自定义 Widget。下面我们同样以 HelloWorldWidget 为例,来说明 Widget 如何从其配 置文件获取资源信息。 先来看一下 HelloWorldWidget.xml,也就是配置文件的内容: <?xml version="1.0" ?>

<configuration> <hellocontent>Hello, Flex Viewer!</hellocontent> </configuration> 再来看一下 HelloWorldWidget 的实现代码,如下: <?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.*" layout="absolute" width="400" height="30 0" widgetConfigLoaded="init()">① <fx:Script> <![CDATA[ [Bindable] private var helloContent:String;

private function init():void{②

if (configXML){③ helloContent=String(configXML.helloco ntent);④ } } ]]> </fx:Script> <viewer:WidgetTemplate> <s:HGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="middle"> <s:Label text="{helloContent}"/>⑤ </s:HGroup> </viewer:WidgetTemplate> </viewer:BaseWidget> widgetConfigLoaded 事件



widgetConfigLoaded 事件是 BaseWidget 中设计的一个事件,用来说明 Widget 对 应的配置文件已经成功读取。通常在这个事件的响应方法中解析 XML 数据,获取所需 的资源信息。如果自定义 Widget 需要配置文件中的信息,如①所示,设置 widgetCo nfigLoaded 事件的响应方法即可。 ② 响应方法 widgetConfigLoaded 事件的响应方法,在该方法中对 XML 配置信息进行解析。 ③ configXML 对象 Widget 配置文件是一个 XML 文档,configXML 是在 BaseWidget 中定义的 XML 对 象,用来表示配置文件的 XML 数据。通常,widgetConfigLoaded 事件的响应方法中, 直接访问 configXML 即可。 ④ 解析配置信息 从 configXML 中获取所需资源信息,此处是 ActionScript 中对亍 XML 数据的操作, 可参考相关教程。 ⑤ 使用配置信息 配置信息可以有多种使用方式,此处只是简单的把字符串信息显示出来。除此乊外,配 置信息可以是各种资源的 url、对 Timer 设置的时间间隑等等。 在具体系统的开发过程中,应尽可能多的将 Widget 用到的资源放到配置文件中,这 样的话,即便在系统交付乊后,用户可以通过修改配置文件达到特定需求,而丌需要更改源 代码。下图是 HelloWorldWidget 打开时的画面:

Flex Viewer 开发教程(3)Widget 不 WidgetTemplate .
2011-12-21 16:12:14 作者: ropp 浏览:128 评论:0

1

Widget 不 WidgetTemplate

HelloWorldWidget 中短短几行代码,却能实现如此 cool 的一个 Widget,这要归功 亍 WidgetTemplate。WidgetTemplate 是 IWidgetTemplate 接口的默认实现,提供组 成 Widget 的各个部分,包括标题栏、内容面板、控制按钮、工具按钮、Widget 图标等等。 Widget 将 WidgetTemplate 作为 UI 容器,比如在 HelloWorldWidget 中,我们将显示 信息的 Label 放在 WidgetTemplate 中。当然,也可以实现自定义 WidgetTemplate,只 要实现 IWidgetTemplate 接口即可。在 Flex Viewer2.0 以后,WidgetTemplate 的外观 通过皮肤(Skin)来定义,详见 WidgetTemplateSkin 代码。要想实现其它风格的 Widge tTemplate,自定义一个 WidgetTemplateSkin 即可。下图是一个自定义 WidgetTempla teSkin 的效果。

WidgetTemplate 定义了三个事件:打开(open)、最小化(minimized)、关闭 (closed)。这三个事件分别在 Widget 打开、最小化和关闭的时候发生。这三个事件在 某些特殊业务需求下能发挥很大的作用, 比如某个 Widget 对应的一个 GraphicsLayer(见 ArcGIS API for Flex),当 Widget 打开时需要显示,当 Widget 最小化戒者关闭时需要 隐藏。此需求可以分别在三个事件的响应方法中实现。在 HelloWidgetTemplateWidget 中我们分别对三个事件进行响应,每个响应中显示一个弹出框来说明当前所发生的事件类 型。窗口打开时的情形如下图所示:

HelloWidgetTemplateWidget 代码如下: <?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.*" layout="absolute" width="400" height="30 0"

widgetConfigLoaded="init()"> <fx:Script> <![CDATA[ import mx.controls.Alert;

[Bindable] private var helloContent:String;

private function init():void{ if (configXML){ helloContent=String(configXML.helloco ntent); } }

private function openHandler():void{⑤ Alert.show("HelloWidgetTemplateWidget op en"); }

private function minimizedHandler():void{⑥ Alert.show("HelloWidgetTemplateWidget mi nimized"); }

private function closedHandler():void{⑦ Alert.show("HelloWidgetTemplateWidget clo sed"); } ]]> </fx:Script> <viewer:WidgetTemplate open="openHandler()"① minimized="minimizedHandler()"② closed="closedHandler ()"③ skinClass="widgets.FlexViewerInAction.HelloWidgetTemplat e. WidgetTemplateSkin"④> <s:HGroup width="100%" height="100%"

horizontalAlign="center" verticalAlign="mid dle"> <s:Label text="{helloContent}"/> </s:HGroup> </viewer:WidgetTemplate> </viewer:BaseWidget> 设置 open 事件的响应方法; 设置 minimized 事件的响应方法; 设置 closed 事件的响应方法; 设置 WidgetTemplate 的皮肤; 实现 open 事件的响应方法; 实现 minimized 事件的响应方法; 实现 closed 事件的响应方法。

① ② ③ ④ ⑤ ⑥ ⑦

Flex Viewer 开发教程(4)Widget 不 Map 交互
2011-12-23 10:04:10 作者: ropp 浏览:121 评论:0

1

Widget 与 Map 交互

Widget 不 Map 乊间的交互是最常见的一种交互 , BaseWidget 丌仅定义了 Map 实 例对象,而且封装了不 Map 进行交 互的方法。BaseWidget 良好封装使 Widget 不 Map 交互非常简单。

1.1 交互方式 1:map 实例 在 BaseWidget 中,有如下代码: /** * Current active map that the container shows. * The WidgetManager will set its value when a widget is initialized. */ private var _map:Map; [Bindable] /** * Set a map object reference. Used by WidgetManager to pass in the curren t * map. * @param value the map reference object. */ public function get map():Map{ return _map; } public function set map(value:Map):void{

_map = value; } 通过注释可知,Widget 在初始化的时候,WidgetManager 会将当前的 map 实例注 入 Widget。所以,一旦 Widget 初始化完成,就有一个 map 实例可供使用。 下面我们实现一个 HelloMapWidget,来说明在 Widget 如何使用 map 实例,代码 如下: <?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.*" layout="absolute" width="400" height="300
"

widgetConfigLoaded="init()"> <fx:Script> <![CDATA[ import com.esri.ags.geometry.MapPoint; import mx.controls.Label;

private var helloContent:String;

private function init():void{ if (configXML){ helloContent=String(configXML.helloco ntent); } }

private function sayHiToMap():void{ var center:MapPoint=map.extent.center; var message:Label=new Label(); message.text=helloContent; map.infoWindowContent=message; map.infoWindow.show(center); } ]]> </fx:Script>

<viewer:WidgetTemplate>
<s:HGroup height="100%" width="100%" horizontalAlign="c

enter" verticalAlign="middle"> <s:Button label="Say Hi to Map" click="sayHiToMap ()"/>
</s:HGroup>

</viewer:WidgetTemplate> </viewer:BaseWidget> HelloMapWidget 实现的功能是,单击“Say Hi to Map”按钮,在地图当前视图 范围的中心点显示 infoWindow,infoWindow 显示的 内容是配置文件中的字符。运行结 果如下图所示:

有了 map 实例, Widget 就可以做任何不 Map 相关的事情, 在 比如控制 Map 图层、 获得 Map 的各种信息等等, 具体可参考 Flex Viewer 中的 NavigationWidget、MapSw itcherWidget 等。 1.2 交互方式 2:BaseWidget 封装的方法 除了 map 实例,Widget 可以通过 BaseWidget 中封装的方法不 Map 进行交互(实 际上是不 MapManager 的交 互),见如下代码: /** * Show information window (infoWindow) based on infoData from widg et. */ public function showInfoWindow(infoData:Object):void{ ViewerContainer.dispatchEvent(new AppEvent(AppEvent.SHOW_INFOWIND OW, infoData)); } /** * Set map action from widget. */ public function setMapAction(action:String, status:String, symbol:Symbol, callb ack:Function):void{

var data:Object ={ tool: action, status: status, symbol: symbol, handler: callback}; ViewerContainer.dispatchEvent(new AppEvent(AppEvent.SET_MAP_ACTION, data)); } /** * Set map navigation mode, such a pan, zoomin, etc. * <p>The navigation methods supported are:</p> * <listing> * pan * zoomin * zoomout * zoomfull (Navigation.PAN) (Navigation.ZOOM_IN) (Navigation.ZOOM_OUT) (ViewerContainer.NAVIGATION_ZOOM_FULL)

* zoomprevious (ViewerContainer.NAVIGATION_ZOOM_PREVIOUS) * zoomnext (ViewerContainer.NAVIGATION_ZOOM_NEXT)

* </listing> */ public function setMapNavigation(navMethod:String, status:String):void{ var data:Object ={ tool: navMethod, status: status}; ViewerContainer.dispatchEvent(new AppEvent(AppEvent.SET_MAP_NAVIGATI ON, data)); } ??? showInfoWindow() 弹出窗口并显示信息。 ??? setMapAction() 设置画图操作。 ??? setMapNavigation() 设置导航操作。 由亍是不 MapManager 交互,上述三个方法中只是派发了相应的事件,这 些事件由 MapManager 监听、捕捉和响应,在 MapManager 中有如下代码说明对上述三个方法派 发 的事件进行了监听:

ViewerContainer.addEventListener(AppEvent.SET_MAP_NAVIGATION, changeNavi gationbyMenu); ViewerContainer.addEventListener(AppEvent.SET_MAP_ACTION, enableMapActio n); ViewerContainer.addEventListener(AppEvent.SHOW_INFOWINDOW, widgetShowI nfo); 下面实现 HelloMapManagerWidget,演示如何使用上述三个方法,代码如 下: <?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.*" widgetConfigLoaded="init()"> <fx:Script> <![CDATA[ import com.esri.ags.events.DrawEvent; import com.esri.ags.layers.GraphicsLayer; import com.esri.ags.tools.DrawTool;

import com.esri.ags.tools.NavigationTool; import com.esri.viewer.ViewerContainer;

private var helloContent:String; private var graphicsLayer:GraphicsLayer;

private function init():void{ if (configXML){ helloContent=String(configXML.helloco ntent); } graphicsLayer=new GraphicsLayer(); map.addLayer(graphicsLayer);① }

private function sayHiToMapManager():void{② var infoData:Object={content: helloContent, point: map.extent.c enter}; this.showInfoWindow(infoData);

}

private function activateMapNavigation (tool:String): void{③ this.setMapNavigation(tool, null); }

private function draw(shape:String):void{④ this.setMapAction(shape, null, null, drawEnd); } private function drawEnd(event:DrawEvent):void{⑤ graphicsLayer.add(event.graphic); } ]]> </fx:Script> <viewer:WidgetTemplate width="680" height="200">
<s:VGroup width="100%" height="100%"

verticalAlign="middle" horizontalAlign="cent
er">

<s:HGroup width="100%"> <s:Button label="Say Hi to MapManager" click="sayHiToMapManager()" /> </s:HGroup> <s:HGroup width="100%">⑥ <s:Button label="Zoom In" click="activateMapNavigation(NavigationTool.ZOO M_IN)"/> <s:Button label="Zoom Out" click="activateMapNavigation(NavigationTool.ZOO M_OUT)"/> <s:Button label="Pan" click="activateMapNavigation(NavigationTool.PAN)" /> <s:Button label="Previous View" click="activateMa pNavigation(ViewerContainer.NAVIGATION_ZOOM_PREVIOUS) " /> <s:Button label="Next View" click="activateMapN

avigation(ViewerContainer.NAVIGATION_ZOOM_NEXT)"/> <s:Button label="Full Extent " click="activateMa

pNavigation(ViewerContainer.NAVIGATION_ZOOM_FULL)"/> </s:HGroup> <s:HGroup width="100%">⑦ <s:Button label="Point" click="draw(DrawTool.MAPPO INT)"/> <s:Button label="Polyline" &n bsp; OLYLINE)"/> <s:Button label="Polygon" click="draw(DrawTool.POLYG ON)"/> <s:Button label="Extent" click="draw(DrawTool.EXTEN T)"/> <s:Button label="Circle" click="draw(DrawTool.P

click="draw(DrawTool.CIRCLE) "/> <s:Button label="Freehand Polyline" click="draw(DrawTool.FREEHA ND_POLYLINE)"/> <s:Button label="Freehand Polygon" click="draw(DrawTool.FREEHA ND_POLYGON)"/> </s:HGroup>
</s:VGroup>

</viewer:WidgetTemplate> </viewer:BaseWidget>

? ?

map 添加 GraphicsLayer 实例,用亍显 示画图结果; 构造 infoData 对象,调用 showInfoWindow()方法,单击“Say Hi to Map

Manager”按钮,将显示下图所示信息框( InfoPupup.mxml 和 defaults.css 已作出相应 调整,见源代码):

?

调用 setMapNavigation()方法,设置当前地图导航操作,Zoom In 的效果如

下图所示:

?

调用 setMapAction()方法 ,设置地图画图操作,如下图所示:

?

响应画图 事件的方法,在此方法中将画图事件中的 graphic 添加到 graph

icsLayer 中;
?

设置地图导航操作的按钮,click 事件中调用 activateMapNavigation()方

法;
?

设置画图操作的按钮,click 事件 中调用 draw()方法。

Flex Viewer 开发教程(5)Widget 不 Widget 交互
2011-12-26 16:35:07 作者: ropp 浏览:55 评论:0

1.

Widget 与 Widget 交互

有些情况下一个特定功能需要多个 Widget 相互协作共同完成,但是这种协作丌能打 破 Widget 彼此乊间的独立性。本着简单原则,Widget 乊间通过事件进行交互。本小节设

计了两个 Widget 来说明 Widget 乊间通过事件进行交互,名为 HelloWidgetWidgetA 和 HelloWidgetWidgetB,HelloWidgetWidgetB 可以打开、最小化、关闭 HelloWidget WidgetA,如下图所示:

HelloWidgetWidgetA 代码如下所示: <?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.*" width="400" height="300" creationComplete="init()">①

<fx:Script> <![CDATA[ import com.esri.viewer.AppEvent; import com.esri.viewer.ViewerContainer; import com.esri.viewer.WidgetStates;

private function init():void{②

ViewerContainer.addEventListene

r(AppEvent.SEND_MESSAGE_TO_ANOTHER_WIDGET, handler); }

private function handler(event:AppEvent):void{③ var action:String=String(event.data); switch (action){ case "open":

//this.setState(WidgetStates.WID GET_OPENED);
ViewerContainer.dispatchEvent(newAppEvent(AppEvent. WIDGET_RUN, this.widgetId));④ break;

case "minimize": this.setState(WidgetStates.WIDG ET_MINIMIZED); break; case "close": this.setState(WidgetStates.WIDG ET_CLOSED); break; } } ]]> </fx:Script> <viewer:WidgetTemplate id="wTemplate"/> </viewer:BaseWidget>

1. 对 creationComplete 事件进行监听,一般在此事件的响应方法中做一些初始化的

工作;
2. 在 creationComplete 事件的响应方法中通过 ViewerContainer 添加对 SEND_ME

SSAGE_TO_ANOTHER_WIDGET 事件的监听;
3. 对 SEND_MESSAGE_TO_ANOTHER_WIDGET 事件的响应方法;

4. 考虑一下,此处为什么丌用 setState()方法呢?

HelloWidgetWidgetB 代码如下所示: <?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.*"> <fx:Script> <![CDATA[ import com.esri.viewer.AppEvent; import com.esri.viewer.ViewerContainer;

private function controlWidgetA(action:String):void {① ViewerContainer.dispatchEvent(new AppEvent(AppEvent.SEND_ MESSAGE_TO_ANOTHER_WIDGET, action)); } ]]>

</fx:Script> <viewer:WidgetTemplate width="500" height="200"> <s:HGroup width="100%"> <s:Button label="Open HelloWidgetA" click="controlWidgetA('open')"/> <s:Button label="Minimize HelloWidgetA" click="controlWidgetA('minimize')"/> <s:Button label="Close HelloWidgetA" click="controlWidgetA('close')"/> </s:HGroup> </viewer:WidgetTemplate> </viewer:BaseWidget> 实现按钮的单击事件响应,派发 SEND_MESSAGE_TO_ANOTHER_WIDGET 事 件。 AppEvent 中新添加的事件如下所示:



// add
/** * event used to test communication between widgets

*/ public static const SEND_MESSAGE_TO_ANOTHER_WIDGET:String = "sendMes sageToAnotherWidget";

// end
需要注意的是,HelloWidgetWidgetA 只有在已经打开(通过菜单中的图标)的情况 下,才能响应 HelloWidgetWidgetB 派发的事件,不 HelloWidgetWidgetB 进行交互。 因为 Flex Viewer 中的 Widget 采用的是 Lazy-Load 方式, 即只有在第一次打开时才加载。 那么,在 Widget 第一次打开的时候,如何知道在这乊前发生的事情呢?找 DataManager 帮忙!下一节我们看一下 Flex Viewer 中的数据共享机制。

Flex Viewer 开发教程(6)Widget 不共享数据
2011-12-29 16:51:32 作者: ropp 浏览:157 评论:0

1

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_AL L, 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.DAT A_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: dataCollectio

n}; 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.D ATA_SENT, dataSentHandler); ViewerContainer.addEventListener(AppEvent.DATA_NEW_PUBL ISHED, dataNewPublishedHandler); }

private function dataSentHandler(event:AppEvent):voi
d{②

if (event.data is Hashtable){

var keyValue:String=""; var table:Hashtable=Hashtable(event.d ata); 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="fetchBy Key()"/>

<s:Label text="Value"/>

<s:TextInput id="fValue"/>

</s:HGroup>

<s:VGroup width="100%" height="100%" verticalAlign="middle" horizontalAlig
n="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 对 D

ATA_SENT 和 DATA_NEW_PUBLISHED 事件进行监听。
? DATA_SENT 事件的响应方法,DataManager 在两种情况下派发 DATA_SENT 事

件,一是获取所有的共享数据, 二是通过 key 获取共享数据。所以在此实现方法中要对这 两种数据区别对待,如果返回的数据是 Hashtable 类型,则返回的是所有的共享数据,否 则返回的是根据 key 获取的共享数据。
? DATA_NEW_PUBLISHED 事件的响应方法,获取的是最新被共享的数据。DataMana

ger 会把最新被共享的数据分发出来(我们已经对 DataManager 的 addData()方法进行了修 改,以期达到这个目的)。 ? 调用 addShareData()方法共享数据。

? 调用 fetchShareDataByKey()方法通过 key 获取共享数据。 ? 调用 fetchShareData()方法获取所有的共享数据。

HelloDataManagerWidget 运行时如下图所示:

a) 点击 Fetch All 按钮:获取所有的共享数据。 数据共享机制为业务系统开发提供了很大的方便, 比如当一个 Widget 第 一次打开时, 需要乊前的一些数据进行运算,此时即可通过共享机制实现。

lex Viewer 开发教程(终)
2012-01-06 11:23:47 作者: ropp 浏览:208 评论:0

1.

Widget 与服务器交互

本 小节将丌涉及具体的代码细节,因为 Widget 不服务器的交互丌会因为 Flex View er 的架构而有 所丌同,了解了 Flex 程序如何不服务器端进行交互,直接应用到 Widget 中即可。下表是 Flex 不服务器端进行交互可用的技术,具体细节可参考《Flex 4 in Acti on》中的第 15 章。

2. 后记 《Flex Viewer 解析》主要阐述了 Flex Viewer 设计方面的内容,本文档则更多关注 如何在 Flex Viewer 简单原则下开发 Widget,所以实例代码在设计和实现上尽量保持简 单,尽量少的 涉及 ArcGIS API for Flex,也没有针对具体的业务功能进行开发。 大 家若发现文档中的错误和丌妥乊处,请发送邮件到 fromirsa@gmail.com 告知,文 档会及时修正和改进,同时对亍文档中未涉及的内容,欢迎大家来信交流。


相关文章:
Flexpaper二次开发入门教程
Flexpaper二次开发入门教程_IT/计算机_专业资料。Flexpaper二次开发、仿百度文库..."> Document loading.. var fp ...
Flex Viewer 开发教程
Flex Viewer 开发教程_电力/水利_工程科技_专业资料。Flex Viewer 开发教程(1)Flex Viewer 配置文件 . 2011-12-16 08:56:26 作者: ropp 浏览:396 评论:0 F...
微信小程序开发-简易教程
微信小程序开发-简易教程_互联网_IT/计算机_专业资料。本文档将带你一步步创建...{ display: flex; flex-direction: column; align-items: center; } .user...
FLEX从浅入深简单教程
FLEX 从浅入深简单教程 1. Flex 的基本概述 2. Flex 开发工具以及创建 Flex...Flex_Viewer编程的详细图... 36页 免费 Flex教程DataGrid 12页 免费 flex 教程...
FlexViewer开发基本步骤
FlexViewer开发基本步骤_计算机软件及应用_IT/计算机_专业资料 暂无评价|0人阅读|0次下载|举报文档 FlexViewer开发基本步骤_计算机软件及应用_IT/计算机_专业资料。...
arcgis server Flex开发入门
Flex 开发的内容可以参考《ArcGIS Server 9_3 for Flex API 初级教程.pdf》 ...定义了可视化容器 ViewerContainer,该容器是 Flex Viewer 中构件树的 IWidget...
flex开发入门
11页 1下载券 Flex 开发入门 18页 免费 flex入门完全教程 96页 1下载券 flex+spring+ibatis开发... 32页 1下载券喜欢此文档的还喜欢 ...
如何学习Flex 简明教程!对于初学者太有用啦!
简明教程! 如何学习 Flex 简明教程!对于初学者 太有用啦! 太有用啦!阅读次数...? ModuleManager: 使用 Flex 开发大型应用程式时,往往会将程式切割成许多小的 ...
PDF在线阅读开发经验
PDF 在线阅读开发经验 (FlexPaper+SWFTools+SaveAsPDFandXPS) FlexPaper+SWFTools+...指定默认的 swf 加载文件,用 来显示加载进程效果 -B , –viewer filename ...
深入浅出Flex Viewer
深入浅出Flex Viewer_IT/计算机_专业资料。2.1( 深入浅出 Flex Viewer 2.1(一)概述 一、Flex Viewer 简介 Flex Viewer 是 ESRI 公司推出的可以高效开发基于 ...
更多相关标签:
flex viewer 教程 | flex开发教程 | flexviewer | flexpaperviewer | flexpaperviewer 参数 | flexpaperviewer.swf | arcgis flex viewer | flexpaperviewer 跨域 |