3.2 让机器动起来——框架启动与小工具初始化

3.2       让机器动起来——框架启动与小工具初始化

本节中我们将会向您解释整个 Fusion 是如何启动的,本节使用的依旧是 MapGuide 开源版本 2.1.0 的源代码。其余版本代码,在细节和行号上可能略有不同,但整体思路是一样的。为了便于解释代码,本节除特殊说明外,我们提到的代码位置和行号均指的是分散加载方式下的代码位置和行号。

3.2.1          工作前的工作——启动代码

前一节我们提到,网页模板文件在加载完毕时,通过调用“ Fusion.initialize(); ”来启动 Fusion 框架的初始化过程。但是,在执行这行代码执行之前, Fusion 就已经执行了一些启动代码( bootstrap )。这些代码主要涉及确定浏览器语言、加载其余 Fusion 脚本代码和加载商业地图脚本等等。这些工作的代码位于“ <FusionRoot>/lib/fusion.js ”文件中,从 1064 行至文件尾。当网页加载到 fusion.js 时候,这些代码就会被执行。

让我们先看看加载其余 Fusion 脚本代码做了什么。前文我们提到了,三种加载 Fusion 框架方式是等效的。其中独立压缩方式和独立文件方式是等效的是很容易理解的,这是因为独立压缩方式仅仅是去掉了无用的空格、换行符号和注释。那么,分散加载方式加载的 fusion.js 仅仅是独立文件方式加载的 fusionSF.js 里面代码的一部分,它们两者之间又是如何保证等效的呢?原来,当 Fusion 中有一个要加载脚本文件的列表( fusion.js 1080-1091 行),这个列表的文件和 fusion.js 放在一起,跟 fusionSF.js 文件是完全等效的。在启动代码中, Fusion 如果发现当前采用的是分散加载方式( Fusion._singleFile 值为 false ),那么就会通过向网页中添加 script 标签的形式来增加新文件。

除了加载其余 Fusion 脚本代码之外,启动代码所做的一个不得不提的工作就是加载商业地图脚本。这个是 2.1.0 新增的一个功能。如果用户需要在地图中加入雅虎、谷歌或者必应地图,那么在启动代码中, Fusion 会检查网页布局文件中是否有 GoogleScript YahooScript 或者 VitualEarthScript 标签,并访问标签里面包含的脚本地址来加载对应的脚本。

当浏览器调用 Fusion.initialize() 脚本的时候, Fusion 便开始了加载的过程。 Fusion 加载的过程分为两步。第一步是将服务器端的网页布局文件变成一个浏览器中包含的信息对象;第二步是根据这个信息对象逐步初始化各个部分。

下面,我们将分别介绍这两个步骤。

3.2.2          从服务器到浏览器——加载应用程序定义

Fusion 框架中,网页布局文件又称为应用程序定义( ApplicationDefinition )文件。在本章其余部分,这两个词可能会交替使用,但两者意思完全相同。

Fusion 是通过地图代理( MapAgent )来获取应用程序定义的。但在此之前, Fusion 先需要知道地图代理的位置。虽然在默认状态下, FusionRoot 是直接放置于“ <WebRoot>/fusion ”文件夹中。但 Fusion 本身相对独立一些,支持将 Fusion 放置在其他文件夹中。这时就需要有一个地方能够告诉 Fusion 地图代理的位置,这个地方就位于 Fusion configuration 属性中, Fusion 通过 Fusion.configuration.mapguide.webTierUrl 属性值找到 MapGuide 的位置(该属性值的形式应当类似“ http://localhost/mapguide ”)。如果您使用的是独立文件加载方式或独立压缩加载方式的话,这个属性是已经被设置好了的 (fusionSF.js 63201-62346 ) 。而对于分散加载方式,这个属性在初始状态下是为定义的,这时 Fusion 会去访问并加载服务器的“ <FusionRoot>/config.json ”做为 Fusion.configuration 的值。也就是说,如果您采用的是分散加载的方式,而且 Fusion 并没有采用默认的文件夹部署,那么,您可以修改这个文件来指示 Fusion 去哪儿寻找地图代理。

找到地图代理的位置后, Fusion 就会初始化一个 Fusion.Lib.ApplicationDefinition 对象( fusion.js 482 行,这个对象的定义位于 <FusionRoot>/lib/ApplicationDefinition.js ”中)。该对象会在初始化的过程中,通过地图代理请求应用程序定义的内容,并把该定义转化成一个浏览器可以处理的 Javascript 对象。

为了获得一个浏览器可以处理的 Javascript 对象,需要先把应用程序定义文件转成一个 Javascript 对象。这个工作是“ <FusionRoot>/common/php/Xml2JSON.php ”页面完成的。 Fusion 把获得的应用程序定义 XML 发送到该页面,该页面就会返回转换后的 JSON 对象。但是这个转换过程仅仅是一个形式上的转换,要想让这个 JSON 对象最终可以被 Fusion 框架处理,还需要进一步把它的各个部分解析成 Fusion 库中相应的实例,这个过程由 ApplicationDefinition parseAppDef 函数来完成。

我们知道,应用程序定义中各个部分是采用了一个层次化的结构最终放置在一个 ApplicationDefinition 根节点下。同样地,转换后的 Javascript 对象也是采用类似的结构放置在一个 Fusion.Lib.ApplicationDefinition 对象中。 XML 标签与浏览器对象的转换关系如表 3-1 所示(限于空间,这里应用程序定义的浏览器对象类别省略掉前缀“ Fusion.Lib ”,其余的浏览器对象省略掉前缀“ Fusion.Lib.ApplicationDefinition ”)。

XML 标签

父节点标签

浏览器对象类别

父对象类别

在父对象中的属性名

ApplicationDefinition

ApplicationDefinition

MapSet

ApplicationDefinition

无对应对象

MapGroup

MapSet

MapGroup

ApplicationDefinition

mapGroups

Map

MapGroup

Map

MapGroup

maps

WidgetSet

ApplicationDefinition

WidgetSet

ApplicationDefinition

widgetSets

Container

WidgetSet

Container

WidgetSet

containers

Item

Container

Item

Container

items

MapWidget

WidgetSet

Widget

WidgetSet

mapWidgetTag

Widget

WidgetSet

Widget

WidgetSet

widgetTags

3-1 XML 标签与浏览器对象的转换关系

要注意的是,这个过程仅仅是一个把 XML 标签转化成对应的浏览器对象,并没有开始对这些对象的初始化。还有一个有意思的地方是,当构造 Widget 对象的时候,构造代码会通过检查是否定义了类“ Fusion.Widget.< 小工具类型 > ”来检查浏览器中是否已经加载了相应的小工具脚本。如果没有,构造代码会调用 Fusion.require 函数来将脚本代码放置到 Fusion 的一个待加载脚本列表中。这个列表将在下一步进行加载。

parseAppDef 将整个应用程序定义文件转换成浏览器对象后, Fusion 就会调用 loadQueuedScripts 函数来加载上一步中发现的没有加载的小工具脚本代码。当所有代码加载完毕之后, Fusion 就会开始整个小工具的初始化工作。

3.2.3          填空练习——小工具的初始化

当所有代码加载完毕之后, Fusion 会调用 ApplicationDefinition 对象的 create 函数,该函数最终会调用 WidgetSet create 函数,这时,小工具便一个接一个的开始初始化了。

小工具的初始化工作无外乎两个方面:构造一个小工具对象、将其放置到界面中。构造小工具对象的过程相对简单,只要调用“ Fusion.Widget.< 小工具类型 > ”类的构造函数即可。而将小工具放置在界面中的过程,则相对复杂一些。

小工具界面的初始化,有点像一个“填空”过程。

首先, create 函数会检查小工具的 uiClass 属性,并用该属性值作为类名初始化一个界面类。比如,“关于”小工具的 uiClass 属性的值是 Jx.Button ,那么, create 函数会初始化一个 Jx.Button 对象,做为“关于”的界面。在这个初始化过程中,小工具信息中的 label imageUrl imageClass isExclusive 等属性会被作为参数传递到初始化过程中,用来提供初始化的信息。

初始化界面元素之后, create 函数会调用小工具脚本代码的 setUiObject 函数,来允许小工具执行一些定制化的内容。 Fusion.Widget 已经为我们实现了一些常用的代码,比如设置提示、将按钮的按下和弹起事件与小工具的 activate deactivate 函数进行关联等等。如果您需要对于小工具界面提供的空间进行“填空”,一般也会在这个函数内完成。

setUiObject 函数执行完毕后,小工具的界面就初始化完毕了。接下来,需要将小工具的界面添加到页面中。这时候有以下两种情况:

1.       如果小工具不属于任何容器,那么 Fusion 框架就会认为这个小工具的界面是一个独立的页面元素。因此, Fusion 框架去寻找页面中以小工具名称作为标识的 div ,并把小工具的界面“填空”到这个 div 中。举个例子,概览地图( OverviewMap )小工具的名称( name )为 OverviewMap 。那么, Fusion 框架就会通过去寻找网页中标识为 OverviewMap div ,并将小工具的界面利用其 addTo 函数添加到这个 div 中。

2.       如果小工具属于某一容器,那么 Fusion 框架会先寻找相应的容器界面(此前 Fusion 会像添加小工具界面到页面中那样,把容器界面“填空”到相应的 div 中),然后将小工具通过 addTo 函数添加到这个 div 中。

这里我们可以看出,其实在小工具初始化之前,其位于网页中的位置就已经在网页模板中,根据其对应的名称或者容器名称决定下来了。如果您想修改小工具在网页中的位置,您完全不需要改变应用程序定义的内容,而只需要改变网页模板就可以了。

当小工具的界面都被初始化完毕之后,界面就完全加载完毕了。用户就可以通过与界面的交互来使用小工具提供的功能了。

有一点要说明的是,虽然地图小工具也称为小工具,也放置在 Fusion.Widget 命名空间中。但是, Fusion 对于地图小工具的处理是完全不同于其他小工具的。地图小工具在应用程序定义中使用其专用的 MapWidget 标签。 WidgetSet 类也有一个专门的位置来放置地图小工具( mapWidget 属性)。 Fusion.Widget.Map 也并不是继承自 Fusion.Widget 的,甚至其 create 函数的参数列表也不同于普通的小工具。地图小工具与其他小工具的唯一一点相似是,在“填空”的时候,地图小工具也会添加到以其名称为标识的 div 中。

从中我们不难看出,地图小工具的地位是其他小工具无法比拟的。这是因为,地图是网页地理信息系统最核心的部分。大部分用户交互都是通过地图完成的。所以,我们有必要了解一下地图小工具。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值