ArcGIS FlexView 开发指南(中文)


第 1 页 开发指南 用Sample Flex Viewer框架创建GeoWeb应用程序 作者 Moxie Zhang 开发团队 Corporate Sales, ESRI Inc. 文件名 FlexViewerDevelopersGuide.pdf 上次修改 2008-11-21 资料权限 完全公开 第 2 页 目 录 1 简介..... ................................................................................................................................... 4 1.1 准备知识.......................................................................................................................... 4 1.1.1 技能与软件需求......................................................................................................... 4 1.1.2 获取源代码与所需库.................................................................................................. 4 1.2 文件组织…..................................................................................................................... 5 2 Sample Flex Viewe架构 ....................................................................................................... 5 2.1 架构介绍 .......................................................................................................................5 2.2 Sample Flex Viewer实例的生命周期............................................................................ 6 2.3 Sample Flex Viewer容器............................................................................................... 7 2.4 理解Widget编程模型..................................................................................................... 8 2.5 Widget命名习惯............................................................................................................. 9 3 为Widget开发建一个Flex Builder项目................................................................................ 9 3.1 用Sample Flex Viewer FlexBuilder项目开发一个微件.................................................. 10 3.2 在Sample Flex Viewer的FB项目之外开发一个widget.................................................. 12 3.3 为Flex Builder设置测试服务器...................................................................................... 14 4 开发一个widget ..................................................................................................................... 15 4.1 使用WidgetTemplate模板 ............................................................................................. 16 4.2 获取地图信息............................................................................................................... 17 4.3 在地图上显示widget数据 ............................................................................................. 19 4.4 从地图接收数据(通过单击,画线等操作实现)............................................................. 20 4.5 在widget中控制导航.................................................................................................... 21 4.6 不使用WidgetTemplate模板开发Widget ..................................................................... 22 4.7 开发一个自己的Widget模板 ........................................................................................ 23 4.8 修改或是创建一个主题 ................................................................................................ 24 4.9 Widget的配置............................................................................................................... 25 5 了解Sample Flex Viewer核心代码...................................................................................... 26 5.1 事件总线容器 .............................................................................................................. 26 5.2 依赖注入(DI,也叫控制反转)...................................................................................... 29 5.3 国际化 ......................................................................................................................... 30 第 3 页 5.3.1 使用Flex的国际化特性 .................................................................................................30 5.3.2 本地化设置 ................................................................................................................ 32 5.4 日志和错误处理 .......................................................................................................... 33 6 Sample Flex Viewer框架和Widget部署.............................................................................. 35 6.1 部署一个Sample Flex Viewer应用程序....................................................................... 35 6.2 部署一个widget到Sample Flex Viewer ........................................................................ 35 6.3 安全性考虑 ................................................................................................................. 36 6.3.1 crossdomain.xml ..................................................................................................... 36 6.3.2 网络资源代理........................................................................................................... 37 7 附录A: Configuration XML..................................................................................................37 第 4 页 1 简 介 此文档可供使用Sample Flex Viewer框架来开发基于Flex的ArcGIS API应用程序的开发人员 使用。 1.1 准备知识 1.1.1 技能和软件需求 Sample Flex Viewer框架通过已编译的发布包和源代码包两种形式提供给开发人员。已编译的开 发包 “即开即用”,部署方面快捷;而源代码包是提供给GeoWeb应用程序的开发人员使用。 利用Sample Flex Viewer框架开发应用程序应该充分熟悉Adobe Flex这套软件并且具备足够的开 发基于Flash的RIA网页应用程序的经验。 Adobe Flex的编程语言是ActionScript,一种基于标准JAVA-SCRIPT的强类型的面向对象语言。 对于有过Java,C# ,Javascript等面向对象语言编程经验的开发人员会发现ActionScript这门语 言相对比较容易上手。 要能够开发与GIS相关的程序,首先要具备熟练运用Flex的ArcGIS应用程序接口的知识和经验。 所需软件: † Adobe Flex 3 Builder 标准版 (如果需要用到先进的可视化交互数据, 性能配置文件, 或 者需要用的第三方集成测试工具的话,推荐安装Adobe Flex 3 Builder企业版) † Adobe的软件开发包 (如果无法获取Flex Builder的话) † 针对Eclipse的Subversion插件 (仅适用于需要用到Svn代码版本控制软件的开发人员) † Flex的ArcGIS 应用程序接口 (如果需要开发GIS应用程序的话) 1.1.2 获取源代码和所需库 源代码将会以zip压缩文件的格式包含在发布包中,文件名为flexviewer-src-1.0-.zip。发布包的压 缩文件可以从ESRI公司的资源网站ArcGIS API for Flex代码库下载,文件名为AS15905.zip(当 上传更新的版本文件名上的数字会相应更新)。 压缩文件的根文件夹FlexViewer包所有的源文件,库文件,文档以及FB项目文件。库文件的子 文件夹libs中包含Flex的ArcGIS应用程序接口组件集swc文件,它是用来创建这个发布包的。 Widget 编程模型库也包括在源代码的压缩文件中。用它开发微件不需要访问和编译整个Sample 第 5 页 2 Sample Flex Viewe架构 2.1 架构介绍 Flex Viewer架构的源码。库文件flexviewer-1.0.swc在根文件夹Flex Viewer下面。下一章的方法 二将会讲述如何运用这个库区创建一个Sample Flex Viewer微件。 1.2 文件组织 这一节主要列出了文件组织以及发布包中的主要文件 文件类型 扩展名 包括的文件 文件描述 MXML .mxml 源代码 FLex中定义用户界面的基于XML的标 识语言 ActionScript .as 源代码 开发Flex应用程序的语言 XML .xml config.xml and individual widget configuration files. 用于配置应用程序和微件 Style Sheet .css style.css 定义Sample Flex Viewer的视觉效果 Flash .swf Index.swf Sample Flex Viewer主文件编译后的应 用程序 编译后的微件 例如: AboutWidget.swf 编译后的、独立的微件 style.swf 编译后的样式表,也叫做主题文件 Flex Library .swc agslib-1.0-2008-10-22.swc ArcGIS应用程序接口库 flexviewer-1.0.swc Sample Flex Viewer微件编程模型库 Sample Flex Viewer框架的构建有助于开发和部署针对GeoWeb的应用程序,使得能够充分的发 挥服务器端的空间服务的能力。服务器端的服务通过ArcGIS服务器和ArcGIS在线数据提供。 如下图所示,地球空间信息服务可以由工作在软件即服务方式的伺服机提供商获得,比如 ArcGIS在线数据库,ArcGIS服务器或者是像GeoRSS反馈,KML文件库以及JSON/REST数据等 网络数据源。基于Sample Flex Viewer框架开发的应用程序所消耗的数据可以由服务器端提供, 也可以是从移动设备运行动态生成的数据,如现场项目师的笔记本电脑或智能手机。 第 6 页 menu control ArcGIS在线数据 Sample Viewer架构 ArcGIS 服务器 其他服务和反馈 手持移动设备 2.2 Sample Flex Viewer实例的生命周期 一个Sample Flex Viewer框架的实例从开始应用程序的设计到用户看到带微件的界面经历了一个 简单的生命周期。期间主要的5个事件如下: 1. Flash播放器从加载和运行容器文件开始一个Sample Flex Viewer框架的应用程序。 2. 这个Flex Viewer容器再从网络服务器加载XML格式的配置文件和皮肤文件并应用于整个应用 程序。 3. 在配置文件的基础上,Flex Viewer容器会从ArcGIS在线数据和ArcGIS9.3服务器下载相关的 地图信息,然后会从配置文件中加载并且在控制条上显示菜单和来自配置文件的标记信息。 4. Flex Viewer容器的微件管理器会从XML配置文件指定的URLs下载并加载相关的微件文件 (一般是swf文件) 5. 用户利用微件来实现各种业务逻辑. 第 7 页 2.3 Sample Flex Viewer容器 The Sample Flex Viewer容器使设计人员能够摆脱地图管理、地图导航、应用配置、组件间的通 信、数据管理等繁重复杂的编程工作,专注于核心业务功能开发,尤其是那些利用ERSI公司的 ArcGIS技术的网络应用开发人员。而且只需要在Flex Viewer应用程序的配置文件中增加配置 项,就可以将功能以widget的形式快速部署到已有的Flex Viewer应用中。 Sample Flex Viewer容器由一系列高内聚、低耦合组件组成(如下图所示)。容器会把关注的任 务交给相应的组件去完成。这种设计方法不但简化了代码维护和定制,而且缩小了模块编写过程 中产生的阻力。 Sample Flex Viewer容器 Config Manager UI Manager Control Bar Map Manager Widget Manager Data Manager Config Object CSS Theme Skin Menus Items Map Layers Widgets Last Data Sets Symbols Branding Brand Navigation 第 8 页 2.4 理解Widget编程模型 经过编译的widget是一个独立的SWF(Flash)文件,可在Flex Viewer程序中共享、移动和配 置。 Widget封装了一系列独立并且针对性很强的业务逻辑,用户可以在其中执行任务。在一个面 向服务的环境下,一个widget可以代表是一种服务或者是一套相关的服务,用户可以很明了 的用它来执行一个业务功能。widget不仅为用户提供了可视化的界面,也能够连到服务器端 的资源,像是来自ArcGIS服务器或是ArcGIS在线数据库的地图服务。 一系列相互关联的widget加上清晰定义好的业务操作流程组成了业务解决方案。而且这样的 方案可以应用于企业级的业务进程中。轻量级的Flex Viewer Widget编程模型使得开发人员可 以轻易定制widget,避免了将widget整合到Flex Viewer应用程序中所需的底层代码开发。 widget编程模型包含了两个ActionScript类(其中一个后为mxml类)以及两个ActionScript接 口。后面一个章节将会讲述如何使用这些类以及接口的相关细节。 IBaseWidget Interface (IBaseWidget.as) 这个接口定义了WidgetManager管理微件的通信方法。而基础widget类BaseWidget则要 来实现这个接口。 BaseWidget Class (BaseWidget.as) 这个是widget的基类,所有的微件都要继承这个类。通过扩展BaseWidget这个父类, WidgetManager会验证所有扩展了BaseWidget的MXML或AS类是否为可部署的微件。另 外,扩展了BaseWidget的类能够被编译为一个独立的SWF文件。 每个Flex Viewer框架下的微件必须继承BaseWidget这个父类。 IWidgetTemplate (IWidgetTemplate.as) 这个接口定义了widget模板能够被BaseWidget识别所需要的一般操作。是使用一个widget模 板还是使用内置的widget模板通常是可选的。内置的WidgetTemplate类要实现 IWidgetTemplate这个接口。 WidgetTemplate (WidgetTeamplate.mxml) 这是一个内置的widget模板,它是一个为widget提供基本的布局和行为的用户界面组件。这 些布局和行为包括一个标准的窗口面板,带有自定义图标按钮的标题栏等组件。使用这类模 板,使得widget开发者能够把更多的时间和精力放在核心的业务需求上面。内置的widget模 第 9 页 板通常也能被widget开发者用来定制属于自己的widget模板,前提是必须实现 IWidgetTemplate这个接口。 2.5 Widget命名习惯 Widget 类: 一般来讲一个widget类得有”Widget”这样一个后缀,比如”NameWidget.mxml” Widget 的配置文件: 一个好的习惯就是,将widget的配置文件取相同的文件名,只是扩展名采 用xml,比如NameWidget.xml。 3 为Widget开发建一个Flex Builder项目 即使你已经能够在盒外部署并运行一个编译好的Flex Viewer程序,开发过程中也有许多的用 例使得你不得不参考Sample Flex Viewer的完整源代码。比如说,你可能会想修改原来的示例 代码程序或者是为了开发自定义的微件而扩展Sample Flex Viewer的程序。这一章将会讲述如 何使用Sample Flex Viewer示例程序建一个Flex项目并且进行编译。 有了示例代码Sample Flex Viewer就能够容易建一个自己的Flex Builder项目。下面介绍了解 压源代码并导入到Flex Builder项目中的步骤: 第一步: 解压缩项目包; 压缩文件flexviewer-src-1.0.zip包括了发布包flexviewer-1.0.zip,根文件夹为FlexViewer。这 样就不需要手工创建一个根文件夹,除非要另外命名。在电脑选择一个放置项目文件的文件夹 并把zip文件解压出来。 使用Flex Builder创建widget有两种方法,后面一部分将会更加详细地讲述这两张方法。 第二步: 导入解压的文件到 Flex Builder项目; 具体可以按照下图所示步骤进行导入: 在导入的对话窗口,找到前面解压的文件夹并导入所有项目文件,点击Finish。 第三步: 创建Sample Flex Viewer; 现在需要开始创建Sample Flex Viewer项目。在导航栏选择“项目”,返回在项目菜单选择 “创建项目”命令。如图所示: 第 10 页 一旦项目创建成功,就可以进行widget开发了。 3.1 用Sample Flex Viewer FlexBuilder项目开发widget 创建一个widget,就需要在Sample Flex Viewer项目中新建一个widget类,具体步骤如下: 第一步: 新建一个 MXML类,文件名为 MyFirstWidget.mxml; 在Flex导航中右键Flex Viewer项目名,并选择“New – MXML Component”命令。 第二步: 填写MXML组件创建对话框; 一定要使用BaseWidget作为新建的widget类的父类,这点很重要。 你可以把新建的widget文件放到项目里面任何位置,建议给微件专门建一个文件夹,这样便于 和其他的文件分开。一旦填写完对话框中相关的选项和内容点击“Finish”按钮。下图创建了 一个新的文件夹并在里面建了一个微件,名字是MyFirstWidget.mxml。 第 11 页 第三步: 将MyFirstWidget添加到Flex Builder工程模块列表; 提醒: 这一步很关键,它使得Flex Builder能够编译你的微件并生产一个相应的独立的swf文 件。 R右键项目名并选择“属性”,在属性窗口进行如下操作: † 在左边列表中选择“Flex Modules” † 点击“Add ”按钮并找到新建的MyFirstWidget.mxml文件 † 点击OK. 这个新建的widget能够被自动优化到index.mxml文件中。 第 12 页 第四步: 编译所创建的微件。 对整个Sample Flex Viewer执行build命令,现在新建的widget已经是整个项目的一部分了。 一旦build命令成功执行完毕,整个项目会在bin-debug文件夹或者是其子文件夹(跟src文件 夹下widget文件位置对应)下会创建一个新的widget的swf文件。只有编译成swf文件才能被 用来单独用来在Sample Flex Viewer应用程序中共享或者是进行部署。然而,现在也只是建 了一个空的微件,并没有向其中添加任何用户界面的组件或者是功能逻辑。后面一个章节将 会讲述如何进一步开发这个微件。 这种开发方式的好处在于: † 不需要为建一个widget创建整个Sample Flex Viewer项目 † 编译的时候,widget将自动被优化。这会减小widget文件的大小,优化加载运行 widget的性能 需要注意的是: † 你需要获取Sample Flex Viewer的源代码并且能够成功编译之。 3.2 在Sample Flex Viewer的FB项目之外开发一个widget 其实我们要开发一个widget的话并不需要导入整个的Sample Flex Viewer的代码,可以只 需要导入widget编程模型的组件库flexviewer-1.0.swc,同样还需要Flex的应用程序接口库 来开发一个ArcGIS API for Flex的应用程序。这一章将会展示如何使用widget编程模型库 而不是整个的Sample Flex Viewer示例代码来开发一个widget。 第一步:新建一个Flex项目; 然后点击”Next”接受默认的设置,并点击”Finish”完成创建向导。 第二步:导入项目所需的Flex库; 默认情况下,Flex Builder会提取libs文件夹下面的所有库文件并将之导入项目文件夹结构中。 这样的话,你只需要把所需要的库文件放到libs文件夹下即可。同样,你也可以根据需要把库 文件放到其他位置,但是需要修改项目属性向导中相关内容。 如下图所示: 第 13 页 到目前为止我们共拷贝了两个库文件,一个是widget编程模型库文件,另外一个是ArcGIS的 Flex应用接口库文件。 注意:新建的项目里面有一个Flex Builder自动生成的文件WidgetSample.mxml,尽管对于开发 widget没有多大用处但我们最好不要删掉它。 第三步:调整编译器以减小widget的大小; 这一步的操作将会告诉Flex Builder不要把Flex软件开发工具的相关代码都导入到widget 的编译 文件中,这样就能显著减小生成的swf文件的大小。 打开项目属性对话框,在Flex Build Path中改变framework linkage ,在下拉列表中选择 Runtime shared library (RSL)。 第四步:创建一个widget类; 在组建创建对话框中: 第 14 页 必须使widget扩展BaseWidget这个父类,所以Based On中要选择BaseWidget,然后点击Finish。 第五步:把新建的widget添加到Flex Builder的模块列表; 注意:这一步非常关键,使得Flex Builder把创建的widget编译到一个独立的swf文件中。 在”Flex Modules”中添加新建的widget文件MyFirstWidget.mxml到列表,选择”Do not optimize”,然后点击OK,新建的文件中的代码如下: 第六步:创建整个项目; 一旦创建了这个项目你会发现在bin-debug文件夹下面多了一个名字为MyFirstWidget.swf的swf文 件,这个是所创建的widget能够用来共享和部署的swf文件。 当前生成的widget还没有任何的用户界面元素和功能逻辑。 这个章节表示了如何不用整个Sample Flex Viewer的源代码来创建一个widget的另一种方法。后 面一章会进一步讲述如何创建功能更强大的widget并在Flex Viewer的应用程序中进行部署。 3.3 为Flex Builder设置测试服务器 当用Flex Builder测试一个Flex应用时,它默认情况下会调用系统自带浏览器直接从bin-debug文 件夹打开相应的html文件。浏览器中URL地址形式如file:///C:/AllESRI/moxie/dev/FlexViewer/bin -debug/index.html. 然而,尽管用这种方法也能运行程序,但这却不是测试Flex应用程序的最好办法。如果要模拟一 个从HTTP服务器运行的Flex应用程序配置的环境,最好还是需要用一个本地的服务器做测试。 注意: The best practice is to always setup a local web server to test your Flex application. 最 好的方法是设置一个本地的网络服务器来测试Flex应用。 使用Windows开发环境作说明如下: 第 15 页 第一步:创建一个IIS服务器的虚拟目录,如图; 新创建的虚拟目录应该绑定到所创建的Flex Viewer的FB项目下bin-debug文件夹的磁盘路径,这 里面有生成的测试程序。 在这个例子里,虚拟目录的名字为flexviewer,这样就可以用http://moxie1/flexviewer作为URL从 网络服务器访问这个虚拟目录了,其中moxie1是电脑名称。 第二步:在Flex Builder中配置指定到所创建的虚拟目录; 打开Sample Flex Viewer应用程序的项目属性窗口,在flex Build Path中进行设置如下,键入虚拟 目录的URLhttp://moxie1/flexviewer作为输出文件夹的位置。 一旦这个URL设置完成,接下来就可以从Flex Builder中运行自己的程序,它就会从指定的网络服 务器路径下加载运行了。 4 开发一个widget 尽管前面两个章节讲述了两种widget项目开发的途径,但其实它们实际的核心功能开发的原理是 一样的。这一章我们会用第一种开发方式来做更深入的讲解。我们先假设widge的开发员很熟悉 Flex的开发环境。 第 16 页 4.1 使用WidgetTemplate模板 在接着2.1节所创建的一个widget文件MyFirstWidget.mxml讲,它的代码如下: 在widget编程模型汇中的WidgetTemplate模板提供的默认widget窗口给出了一套很丰富的内 置组件。使用这个模板添加两行如下代码: 按照如下几个步骤进行配置和部署就能看到运行结果: 第一步:在config.xml中添加创建的widget; 打开config.xml文件添加下面几行代码到标记块。 mywidgets/MyFirstWidget.swf 你可以为创建的widget使用自己的图标,可以是40×40的一个png图像文件,或者gif、jpg文件。 第二步:保存文件并编译整个项目; 具体编译方法参考上一章内容。 第三步:运行Sample Flex Viewer应用程序 右键项目中的index.mxml文件并点击Run Application。 第四步:从工具菜单,点击MyFirstWidget; 下面将会加载并输出显示你的widget。 第 17 页 前面给widget添加的两行代码,是的当前的widget能够有一个标准的视图和感官效果,并且能 够有一些基本功能,比如能够最小化,最大化以及关闭的效果。而且,当前的widget还可以和 Sample Flex Viewer进行内部通信。 接下来就可以在WidgetTemplate模板上添加自己的UI元素并且写自己的业务逻辑了。 4.2 获取地图信息 Sample Flex Viewer是一个基于地图服务开发的应用。一旦这个应用被初始化,通常widget能 够从ArcGIS的地图服务上连接到一个或者多个地图资源。 在基类BaseWidget中定义了一个公共属性map,一个widget被加载以后widget管理器就会把 当前激活的一个地图对象传给这个widget。这个widget的map属性来自com.eari.ags.Map类, 继承于ArcGIS API for Flex。这样的话,你就能够访问到ArcGIS提供的所有的地图参数。 widget的代码写起来就像一个常规的ArcGIS Flex的应用程序一样。 这里有一个例子,在MyFirstWidget中添加了一个按钮。当点击这个按钮时,地图就会自动的 以当前设置的坐标(洛杉矶)为中心。 var point:MapPoint = new MapPoint(-118.24799,33.975004); map.centerAt(point); 在编译并且配置完widget后重新运行Sample Flex Viewer应用程序,如图: 第 19 页 4.3 在地图上显示widget数据 添加图层 建议为每一个新创建的widget添加一个图层,这个图层能够被添加到地图服务中去,具体是 在widgetConfigLoaded这个事件处理器中的init方法进行相关初始化操作。当所有的widget的 配置信息加载完毕并且待命时就会传出一个widgetConfigLoaded事件。相应代码如下: … 然后定义两个事件处理方法来实现图层可见与不可见的切换。 第 20 页 private function widgetClosedHandler(event:Event):void { graphicsLayer.visible = false; } private function widgetOpenedHandler(event:Event):void { graphicsLayer.visible = true; } 4.4 从地图接收数据(通过单击,画线等操作实现) 对于GIS网络应用,除了可视化数据这个特殊用途外,地图还是一个允许用户收集并且处理 地图数据的数据源。或许在用户与地图进行交互的过程中,我们创建的widget需要接收如点 和直线或者多边形这一类的数据来进行处理。那么Sample Flex Viewer以及widget编程模型 就能够用微件通过内置的setMapAction方法来请求或是接收这一类的地图数据。 下面这段示例代码展示了如何激活画图工具来追踪用户在地图上面的点击操作: private function activateTool():void { setMapAction(Draw.POINT, "Click Point", drawEnd); } private function drawEnd(event:DrawEvent):void { var geom:Geometry = event.geometry; var pt:MapPoint = geom as MapPoint Alert.show("Click location: " + pt.x + ", " + pt.y); } 在上面的示例中,点击widget中的按钮会调用activeTool()方法。当一个指定的任务需要用户 点击widget上的按钮时,程序就能够随时从地图上获取一个点的坐标信息。用户下一步需要 做的就是点击地图上任意位置,然后widget就能够接收这个点击行为传送的点信息。具体由 一个回调函数drawEnd()传回参数到setMapAction()方法来实现具体操作。 setMapAction方法 公共方法setMapAcion定义在BaseWidget类里(在BaseWidget.as文件中),这样所有继承 该类的widget就能够自动继承这个特性。该方法定义如下: 第 21 页 public function setMapAction(action:String, status:String, callback:Function):void 参数: action: 这个字符串标记表示ArcGIS API相应的画图工具被激活。下面列出的是ArcGIS Flex API 提供的能够用来访问各种画图工具的字符串标记: extent (Draw.EXTENT) point (Draw.MAPPOINT) line (Draw.LINE) polyline (Draw.POLYLINE) polygon (Draw.POLYGON) multipoint (Draw.MULTIPOINT) freehandpolyline (Draw.FREEHAND_POLYLINE) freehandpolygon (Draw.FREEHAND_POLYGON) status:在控制条的状态栏显示的文本文字; callback:画图操作完成后Map Manager回调的函数。 4.5 在widget中控制导航 当开发一个widget时,为了能够全屏显示,放大或是缩小地图,往往在用例中会需要控 制地图的导航。 比如,当一个widget被关闭后,你需要关闭相应的图层,并且使得地图处于默认的全屏状 态。BaseWidget类提供了一个public方法setMapNavigation用来进行这些操作。代码如下: 在上面的代码中,我们使用一个SWFLoader来加载外部的flash文件到要开发 的widget中。 然而,在这个时钟微件中,你会发现WidgetTemplate模板所提供的很多有用的特性我们根本 没用到。所以,作为widget的开发员要有这样一个共识,那就是随时需要自己写代码来增加 开发widget时所想到的功能,而不是仅仅依赖既有模板所提供的那些特性。 4.7 开发一个自己的Widget模板 Widge编程模型允许开发者创建自己的widget模板。当然,新的widget模板类也需要实现 iWidgetTemplate这个模板接口,因为他是BaseWidget类与widget的模板之间进行交互的核心 接口。 实现一个接口就意味着接口里面所有的方法都必须得以实现。这样,新的widget模板类需要实 现iWidgetTemplate接口中的setTitle,setIcon和setState这三个方法。 下面说明如何创建一个基于Flex组件TitleWindow的widget模板MyTemplate: 第 24 页 接下来向MyTemplate组件中添加一些代码,上面展示的只是一个最简单的widget模板,它能够 接收widget的标题,图标并在TitleWindow组件中进行配置。 下一步我们在mywidgets空间(文件夹)下创建一个新的widget并,命名为MyTempWidget,使 用我们自己的模板,然后在其中添加一个按钮。 上面的代码里面用到自定义模板MyTemplate,编译并部署以后的界面截图如下: 4.8 修改或是创建一个主题 Sample Flex Viewer应用程序的整体观感都能够自定义或是根据需要进行修改。这个主题 (或者叫做‘皮肤’)它跟我们编程代码是分开的。内置的主题名字叫做DarkAngle。 DarkAngle皮肤是使用web上标准的层叠样式列表文件com/esri/solutions/flexviewer/themes/da rkangel/style.css进行构建的。这个CSS文件也能被编译成一个独立的主题文件,一个SWF。 第 25 页 它在运行时被从配置文件config.xml所指定的位置加载到应用程序中。 在config.xml配置文件中stylesheet标签用来提供主题的swf文件的URL地址共应用程序访问。 注意: 对Sample Flex Viewer应用程序作的修改会在运行时自动的应用到各个微件。 下面的步骤说明如何新建一个自己的主题: 第一步:修改DarkAngle的css文件或者新建一个css文件; 新建css文件的话要遵循css标准,可以参考Flex开发文档。 第二步 :改变或者是替换原有图标: 在css文件中有一些使用到内置图标的图像文件元素,你可以修改这些css文件中对于的图 标。 第三步:编译css文件到swf文件中; 这一步很重要只有编译到swf文件才能被Sample Flex Viewer应用在运行时所识别和加载。 要编译这个css文件,只需要右键之并从弹出菜单选择Compile CSS to SWF 命令。 选择了这个命令以后,下次build这个Sample Flex Viewer项目时css文件会被自动编译到一个独 立的swf文件中去。为了能够重新生成主题文件,你可以再编译一下当前的项目。 第四步:添加新建主题文件的URL到config.xml配置文件。 要使用新建的主题文件,只需要修改config.xml中的stylesheet标签,指定到编译好的swf主题文 件位置。 4.9 Widget的配置 通过设计,每个widget能够产生自己的配置文件,这些配置文件的位置在Sample Flex Viewer里 config.xml相应的widget标记对中指定。 relative/urlpath/MyNewWidget.swf 默认情况下,widge编程模型只支持xml格式的配置文件。WidgetManager会把widget配置文件 的URL传给BaseWidget。BaseWidget会加载并分析这个xml格式的配置文件,然后在该文件的 actionScript代码段中设置一个public的属性configXML传递配置参数。 当widget创建完成后可以在自己的widget代码中访问到configXML这个属性。 第 26 页 即使“盒外”开发的Viewer只支持xml格式的配置文件,你也可以用自己的配置文件来格式化 widget代码。这些配置文件会被Flex的HTTPservice服务连接并加载。所以,在加载和分析其他 格式的配置数据时也能使用相同的方法。 5 了解Sample Flex Viewer核心代码 Sample Flex Viewer源代码对公众免费开放,而且在自定义和扩展Viewer的核心功能方面没有 任何限制。具体限制细节请参考发布包中的许可文件。 Sample Flex Viewer的设计是为了使开发者在自定义和扩展时更方便。通过Container Event Bus以及利用依赖注入这两种设计方法可以实现高内聚和低耦合。在自定义Sample Flex Viewer 的内核时,这两张方法很重要。 5.1 事件总线容器 Event Bus容器是一个全局的时间发布器,它是用来促进不同组件直接的交互(或者说信息传 递)。事件总线容器在EventBus这个类(存在于EventBus.as文件)中定义,在SiteContainer 类(存在于SiteContainer.mxml文件)中定义的一组静态代理方法保证了能够顺利访问event bus容器。 下表说明了Configmanager如何加载配置并通过事件容器将其应用到其他组件的。 当Configmanager被初始化以后,它就开始监听事件,如图: public function ConfigManager() { super(); //make sure the container is properly initialized and then //proceed with configuration initialization. SiteContainer.addEventListener(SiteContainer.CONTAINER_INITIALIZED, init); } 在上面的代码中,定义的inti()函数是一个接收到事件后会开始加载配置数据的事件处理器。 其中addEventListener方法又是一个用来访问事件总线的代理方法。 第 27 页 发出事件 Listen Sample Flex Viewer Container架构 Init() 事件总线 发出事件 Container 初始化 init() 配置管理器 ConfigEvent Config() Config() Config() Config() Config() UI Manager Control Bar Map Manager Widget Manager Data Manager 当事件总线容器加载完毕以后SiteContainer容器就会发布CONTAINER_INITIALIZED 事件,具 体参照以下代码: public function init():void { _container = this; _lock = true; //make sure only one container is created. initLogging(); //make sure the event bus is ready. _containerEventDispatcher = EventBus.getInstance(); //tell the modules it's on business. SiteContainer.dispatch(SiteContainer.CONTAINER_INITIALIZED); } 第 28 页 在SiteContainer类中,如上所示,一旦被初始化,就会发布CONTAINER_INITIALIZED事件。通 过使用发布信息方法,组件之间可以在无需其他方法和数据的直接干预下进行监护。最终,这些 组件就通过这些基于事件的消息达到了去耦和分离的效果。这样的话,只要组件之间的消息能够 同步,那么任何组件的修改都不会直接影响到其他组件。 public function init(event:Event):void { configLoad(); } //config load private function configLoad():void { var configService:HTTPService = new HTTPService(); configService.url = "config.xml"; configService.resultFormat = "e4x"; configService.addEventListener(ResultEvent.RESULT, configResult); configService.addEventListener(FaultEvent.FAULT, configFault); configService.send(); } //config result private function configResult(event:ResultEvent):void { try { //parse config.xml to create config data object var configData:ConfigData = new ConfigData(); ………… //dispatch event SiteContainer.dispatchEvent(new AppEvent(AppEvent.CONFIG_LOADED, false, false, configData)); } 在上面的表格中,一旦ConfigManager完成了对配置文件的分析,它就会发布一个带有配 置信息的数据,即如: SiteContainer.dispatchEvent(new AppEvent(AppEvent.CONFIG_LOADED, false, false, configData)); 而所有需要配置信息数据的组件,比如WidgetManager以及MapManager,只需要简单的接收这 个事件发布的数据。 private function init():void { SiteContainer.addEventListener(AppEvent.CONFIG_LOADED, config); … } 第 29 页 这个通过事件总线发布消息的方法可以在Sample Flex Viewer的核心代码中找到。你也可以 用相同的方法来添加组件或是改变组件之间交互的方式。 5.2 依赖注入(DI,也叫控制反转) 依赖注入在通常的电脑编程中指的是向一个软件中的组件添加一个外部依赖的过程。应用控制反 转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用, 传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依 赖的对象的引用,这个责任的反转。 一般情况下,如果一个对象获取了某一个服务资源,这个对象就有责任挂载这个服务:要么是直 接挂载这个服务所在位置的一个依赖关系,要么转到所谓的“服务查询器”并请求它传回一个特 定类型服务实现的依赖。相反,如果使用依赖注入,这个对象只需要简单的提供一个能够挂载住 该特定类型服务依赖的属性即可;当这个对象被创建时,外部机制就会自动生成一个实现了该类 型服务的依赖的属性。 这种依赖注入的方式提供了更好的灵活性,因为使得创建给定服务类型的实现并将其应用于配置 文件而不需要改变使用该类型服务的对象这个过程变得更加简单。在Sample Flex Viewer中,这 个过程体现在创建widget中,DI同样能够被用来创建自定义的widget模板。 下面的代码介绍了WidgetManager是如何运用依赖注入在不需要知道widget的具体实现的情况下 加载相应widget到容器的: private function widgetReadyHandler(event:ModuleEvent):void { var info:IModuleInfo = event.module; moduleTable.add(info.url, info); var id:Number = info.data.id; var label:String = configData.configWidgets[id].label; var icon:String = configData.configWidgets[id].icon; var config:String = configData.configWidgets[id].config; var widget:IBaseWidget = info.factory.create() as IBaseWidget; widget.setId(id); widget.setTitle(label); widget.setIcon(icon); widget.setConfig(config); widget.setConfigData(configData); widget.setMap(map); widgetTable.add(id, widget); var widgetDO:DisplayObject = widget as DisplayObject; addChild(widgetDO); this.cursorManager.removeBusyCursor(); } 第 30 页 在上面代码中,一旦widget模块被加载,他就会转变成IbaseWidget接口类型。而BaseWidget在 这个Di应用中是需要扩展IbaseWidget接口的,这样WidgetManager就不需要知道所操作的widget 是那种类型或是具有哪些功能。WidgetManager只需要调用IbaseWidget中定义的各个方法来和 已加载的widget进行交互。由此,实现widget的时候就不用关心它可能会有多么的复杂,而且这 个实现的过程跟WidgetManager乃至整个Flex Viewer容器是完全分离开的。 在这种情况下,开发员就能够相对自由地开发自己的widget而不受Flex Viewer框架的限制了。建 议在开发自定义的Sample Flex Viewer核心功能时最好通过使用DI来保持这种开发widget的灵活 性。这样做可以通过添加微件而不是修改核心功能的特性来增加功能的一致性。这种方法可以使 得你开发的程序比别人简单许多,而且一定程度上避免了在添加功能特性操作的复杂性。 5.3 国际化 国际化(aka i18n)和本地化(aka l10n)有很多不同之处。国际化(internationalization)是设计和 制造容易适应不同区域要求的产品的一种方式。它要求从产品中抽离所有的与语言,国家/地区 和文化相关的元素。换言之,应用程序的功能和代码设计考虑在不同地区运行的需要,其代码简 化了不同本地版本的生产。开发这样的程序的过程,就称为国际化。国际化根据用户的需求不 同,通常支持多种语言的选择;而本地化通常是针对区域语言。由于跟国际化所依赖的语言元素 不同,它们的设计方法也有所区别。 鉴于Sample Flex Viewer并不是最终设计和开发的成品,它以在代码中以示例的形式支持国 际化和本地化,而并没有将其统一化。 5.3.1 使用Flex的国际化特性 对于Flex如何支撑国际化的具体细节,请参考Flex软件开发工具包(SDK)文档。在Sample Flex Viewer项目中创建了一个子文件夹nls来承载国际化的所有文本字符。比如,这里提供了有两种语 言en_US(美式英语)和fr_FR(法语)。 下面介绍配置Flex Builder使其支持国际化的步骤: 第一步:从项目属性中添加编译器选项; 第 31 页 第二步:把国际化的目录路径添加到Build Source; 第 32 页 路径中的{locale}允许编译器根据步骤一中的编译选项进行操作。 第三步:为语言创建资源文件; 比如说,我们在nls文件夹下的en_US以及fr_FR子文件夹中创建了一个资源文件WidgetTemplat eStrings.properties然后Flex的编译器能够自动识别到扩展名properties。资源文件中的语言文本 字符定义很简单,如下: close=Fermez minimize=Minimisez 第四步:在代码中使用国际化。 比如在WidgetTemplate.mxml中使用国际化资源,需要先定义绑定到指定资源文件的资源绑定。 [ResourceBundle("WidgetTemplateStrings")] 然后创建一个nlsString方法来检索指定语言的字符串。 private function nlsString(nlsToken:String):String { return resourceManager.getString('WidgetFrameStrings', nlsToken); } addTitlebarButton("com/esri/solutions/flexviewer/assets/images/ widget/w_delete.png",nlsString("close"), closeWidget); addTitlebarButton("com/esri/solutions/flexviewer/assets/images/ widget/w_min.png", nlsString("minimize"), minimizeWidget); Flex文档通过这种资源绑定的形式,为支持国际化提供了很多细节性的内容和更先进的技术。 5.3.2 本地化设置 第 33 页 作为一个可选方法,使用配置文件来使得标签字符本地化还是很简便的。Sample Flex Viewer中 内置的widget 比如LiveMapsWidget就是个很好的例子。在这个widget种,标签字符都被定义在 widget的配置文件LiveMapsWidget.xml中。 Layer Visibility Layer Transparency 在这种情况下,如果想覆盖默认语言设置的话,只需要编辑配置文件中的代码即可。 5.4 日志和错误处理 日志和错误处理功能的结合有助于开发功能文档和高质量的软件。 日志处理 在ActionScript和Flex的应用程序的日志记录中常常有很多可用的选项和工具。比如,我们在 SiteContainer中设置了一个日志文件来记录远过程调用协议(RPC)和基于基于网络信息传输过 程中的错误信息。HTTP连接是一类RPC连接,它记录日志文件的代码如下: /** * Initialize the logging. As an example, the logging is setup to only * log the fatal event during the RPC related network communication, * such as HTTP call to obtain configuration file. */ private function initLogging():void { // Create a target. var logTarget:TraceTarget = new TraceTarget(); // Log only messages for the classes in the mx.rpc.* and // mx.messaging packages. logTarget.filters=["mx.rpc.*","mx.messaging.*"]; // Log on fatal levels. logTarget.level = LogEventLevel.FATAL; // Add date, time, category, and log level to the output. logTarget.includeDate = true; logTarget.includeTime = true; logTarget.includeCategory = true; logTarget.includeLevel = true; // Begin logging. Log.addTarget(logTarget); } 第 34 页 这里用的是基于Flex的日志结构。更多详细信息可用参考Flex文档。 错误处理 ActionScript3提供了强大的堪比Java的错误处理机制。然而,相应的编译器却不能够如后者一 样去预测潜在的错误和异常。所以,Flex或者说ActionScript的程序员就要自己使用错误事件处 理器和try-catch异常捕获功能来捕获和处理编程过程中遇到的各种问题。 最好的建议是: † 实现所有可能想到的错误事件; † 尽量尝试使用try-catch异常捕获功能。 一旦发现错误,最好用直白易懂的语言去做标注并解释错误情况。Sample Flex Viewer提供 了一个简单的错误显示功能并能够方便地发送和提示相应的错误信息。对于一个widget ,定 义在BaseWidget中的一个public方法showError()能够用来实现这一功能,例如: showError("This is a test error message!"); 这段代码用来返回Sample Flex Viewer应用程序中出现的错误: 第 35 页 注意到这段错误信息窗口只是一个形式,里面的文本可以使用基本的Html标记进行必要的 设计。在后台,这个错误信息是通过前面一章讲到过对的事件总线来进行传递的。换言 之,错误信息能够在Flex Viewer或者一个widget中根据需要任意传播。 SiteContainer.dispatchEvent(new AppEvent(AppEvent.APP_ERROR, false, false, “the error message string”)); 6 Sample Flex Viewer框架和Widget部署 6.1 部署一个Sample Flex Viewer应用程序 如果你已经下载了Sample Flex Viewer的发布包,那么只需要简单的解压该zip文件到一个 能够访问到网络服务器的文件系统下面即可完成部署。也可能需要配置一下网络服务器是 的加载这个文件系统时输入的URL更简洁。比如在第2.3节中讲到过,可以创建一个IIS的虚 拟目录,这一块的部署跟其他Html的网络应用程序部署方法基本相同。 部署自己编译的Sample Flex Viewer 应用 如果你想使用自己编译的代码来部署Sample Flex Viewer应用程序,建议多做一步,就是用到 Project菜单下的Export Release Build命令。因为去除了相应的debug信息,到处的swf文件往 往会更小。最终,这个应用比Debug后创建的程序更好用。 默认情况下,Flex会创建一个新的文件夹bin-release来放置相关的发布文件。而这个文件夹里面 的所有文件都可以是你的发布包中的内容。也就意味着你可以对它重新命名,把它打包并部署 到特定的网络应用中去。 6.2 部署一个widget到Sample Flex Viewer 假设一个Sample Flex Viewer的应用已经部署并且也已开发好了一个widget,那么下面说明如 何配置这个widget: 第一步:把widget的swf文件复制到特定的文件位置; 一个widge是一个独立于外部的swf文件,你可以把该swf文件拷到Sample Flex Viewer应用的 第 36 页 网络服务器能够访问到的位置或者直接拷到另外一个网络服务器上。 第二步:修改 Sample Flex Viewer应用的配置文件; 配置文件config.xml在该应用程序的根文件夹下,该文件内部的widgets标签下需要添加一个新 的widget入口。 Sample Flex Viewer应用程序支持widget在运行时配置到相同的网络服务器时的相对路径。这 个新添加的widget标签如下: relative/urlpath/MyNewWidget.swf 如果你将widget配置到了另外一个网络服务器,那么增加的widget表情里面的Url应该是一个完 整路径。比如,应用到Icon图像如下: http://another- host/urlpath/MyNewWidget.swf 你可以在widget中明确指定一个配置文件。在这个代码中,定义于BaseWidget的的全局属性 configXML也能够在widget中用到。目前,盒外开发的Sample Flex Viewer的应用程序只支持 XML格式的配置文件并且能够自动地构建configXML属性。如果你想在自己的widget代码中分 析配置数据的话该配置文件可以使用任意格式。 第三步:刷新Sample Flex Viewer应用。 当下次Sample Flex Viewer应用程序被刷新时,新建的widget的配置将会被自动识别并且这个 widget能够在用户界面中通过tool菜单(或者在config.xml文件中自定义的菜单)调用。 6.3 安全性考虑 6.3.1 crossdomain.xml文件 一个虽法律上站不住但事实上却普遍认知的网络浏览器标准就是把安全沙盒强加到浏览器的插 件中。这就意味着当前网页运行的插件只能够访问通过相同网络服务器提供的远程资源。而 Flash这个运行基于Flash开发的软件的浏览器插件也会受到同样的基于Flash开发的应用的沙盒 限制。然而默认情况下,一个Flash应用只有在其他网络服务器部署有一个crossdomain.xml文 第 37 页 件的情况下才能从该服务器URL的根目录下通过相关的Flash应用访问远程资源。 最简单形式的crossdomain.xml文件如下: 这个crossdomain.xml文件能够访问由任何网络上的服务器提供服务的Flash应用程序。可以参 考Adobe Flex的文档来了解设置这个文件的更多内容。 注意:不管任何时候,只要运行Sample Flex viewer程序时发生了安全异常,就要及时检查 crossdomain.xml所部属的资源服务器(比如ArcGIS的地图服务),哪怕只是自己内部组 织的错误。 6.3.2 网络资源代理 在许多情况下,你需要访问其他服务器所提供的资源,比如,各种GeoRSS在线反馈。如果这 些反馈的服务器并没有配置crossdomain.xml文件,那么唯一的选择就是在自己由Flash部署的 服务器上设置一个网络资源代理,并且在代码中指定相关代理。 这个链接提供了一些有关代理的更多资料 http://resources.esri.com/help/9.3/arcgisserver/apis/javascript/arcgis/help/jshelp_start.htm#jshelp/ags_pr o xy.htm 7 附录A: Configuration XML 关于config.xml配置文件的更多解释请参阅源代码中的readme.txt文件。 对于开发者,可以参考发布包里doc/ConfigXMLSchema目录下的xml配置文件,这里定义了 config.xml文件中具体的XML标签。
还剩36页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 15 人已下载

下载pdf

pdf贡献者

31551706

贡献于2011-05-18

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf