Flex Sample App: 建立 Restaurant Finder
关于这个教程
即使您没有Flex的基础,也可以学习此教程, 这不是一个传统的"Getting started" 教程 .这个教程的目标是:
- 展示 Flex Application 的架构的最好实践 .
- 避免传统的缺点,开发您的第一个 Flex Application
此教程用到的一些技术:
- 应用的区分
- 应用之间的宽松联结
- 事件通知
- 在 Model Classes 中使用 ActionScript Classess
- 转换 Java 对象为 ActionScript 对象的类型
- 通过客户端 ActionScript 调用 服务器端的 Java 方法
在这个教程 , 我们将建立一个餐厅门户应用 . 应用有二个模块 :
用户模块(The user module)
这是最终用户查找餐厅的模块 . 用户能使用地点(一种基于地图的选择) 和类别来查找餐厅 . 您能看到顾客的留言并能撰写自己的留言 .在这个教程, 我们从应用分析建立 .
管理模块(The administration module)
这是模块用于管理员 . 管理员能添加, 更新, 并且删除餐厅, 在地图上标记餐厅的地理位置, 等等 . 这是一种典型的数据库维护应用 .我将提供管理模块为你做作为参考应用 . 在以下教程中,我将教你如何配置管理模块 .
要求:
运行这个教程, 您需要下载和安装以下软件和文件 .
1. 安装Flex
- 如果您没有 Flex, 去下载试用版或购买 .
- 如果您还没有安装 Flex, 根据安装说明去安装它 .
2. 如果您没有安装MySql, 安装MySql
- 下载 MySql . 选择最新的版本 ( 本教程使用的是 4.0.20) .
- 解压 MySql 文件到一个临时目录 .
- 运行安装程序 (setup.exe) 并接受所有缺省选择 .
3. 建立餐厅数据库
- 开始 MySql .
c:/mysql/bin>mysqld
- 建立餐厅数据库 .
c:/mysql/bin>mysqladmin – u root create restaurant
- 下载 restaurantadmin_sql.zip (ZIP, 12K) , 并复制其中 restaurant.sql 到 mysql/bin 目录 .
- 建立数据库结构和插入数据 .
c:/mysql/bin>mysql – u root restaurant < restaurant.sql
4. 安装MySql JDBC 驱动
- 下载 MySql JDBC 驱动 .
- 解压文件到一个临时目录 .
3. 复制mysql-connector-java-3.0.14-production-bin.jar 到 [ webapp_root ]/WEB-INF/lib .
注: jar文件的名字也许根据您的下载的驱动版本号不同 .
本地[webapp_root ] 是您使用的Flex服务器应用的根目录 .例如, 如果您使用的是JRUN服务器, webapp_root是: Program Files/Macromedia/Flex/jrun4/servers/default/flex(译注:根据自己的applcation server而不同)
安装管理模块(Installing the Administration Module)
此餐厅应用有二个模块:
- 用户模块
- 管理模块
在此教程, 您将自己建立用户模块 . 我提供管理模块为您作参考应用 .
安装管理模块:
- 下载 restaurantadmin. zip (ZIP, 688K) .
- 解压 restaurantadmib.zip 在您的 Flex 服务器目录 . 例如 , 如果您使用的是 JRUN 服务器 , 解压 restaurantadmin.zip 到 Program Files/Macromedia/Flex/jrun4/servers/default/flex
3. 测试程序 .例如, 如果您选择了JRUN服务器, 浏览管理模块在: http://localhost:8700/flex/restaurantadmin/admin.mxml .
如果您没有修改RemoteObject的whitelist, 将出现以下错误:
这是因为Flex的默认安装后就有很高的安全级别 .您必须编辑RemoteObject的whitelist才能在application server中访问Java class, 修改步骤如下 .
- 编辑在 [ webapp_root ]/WEB-INF/flex 目录下的 flex-config.xml .
- 找到
<remote-objects>
条目 . - 添加
samples.*
包到 whitelist 的unnamed
.
<remote-objects>
<!-- Otherentries-->
<whitelist>
<unnamed>
<source>samples.*</source>
</unnamed>
添加以上语句之后 , client application 能访问 samples 包下的所以类 .
- 再测试程序 , 使用 URL: http://localhost:8700/flex/restaurantadmin/admin.mxml . ( 根据您的配置使用不同的 URL .)
安装教程资源文件
安装资源文件(图象、样式表, 等 .) 在这个教程 .
- 下载 restaurant_tutorial .ZIP (ZIP, 460K) .
- 解压 restaurant_tutorial.zip 到您的 Flex 服务器目录 .
Data Services
使用Flex, 您能选择三个不同的方法访问后台数据 .
1. HTTPService
使用HTTPService, 您的client application可以发送传统HTTP requests到服务器和接收response . 虽然能使用HTTPService 接收响应不同的类型响应, 典型就是使用XML (HTTP的XML) . 您能使用HTTPService 发送请求到任一后台系统: JSP, Servlet, ASP, ColdFustion, CGI, PHP, 等等 .
2. RemoteObject
使用RemoteObject, 您的client application可以在应用服务器里调用Java对象的method,并能接收method的返回值 .返回值可以是value of primitive data type, an object, a collection of objects,等等 .
3. WebService
使用WebService 组件, 您的client application可以在应用服务器里和网络的所有地方调用web services的mothod, 并能接收method的返回值 .返回值可以是value of primitive data type, an object, a collection of objects,等等 .
在这个部分, 您将试验以这三种不同方法访问后台数据 . 您将建立一个餐厅名单在DataGrid 上显示的一种程序 . 将连续地使用HTTPService 、RemoteObject, 和WebService 去查看餐厅名单 .
在这个模块的完成后应用看起来像图4:
实验1: 使用HTTPService
使用HTTPService, 您的client application可以发送传统HTTP requests到服务器和接收response .虽然能使用HTTPService 接收响应不同的类型响应, 典型就是使用XML (HTTP的XML) . 您能使用HTTPService 发送请求到任一后台系统: JSP, Servlet, ASP, ColdFustion, CGI, PHP, 等等 .
在这个实验中, 您使用HTTPService 查询餐厅名单 . HTTPService 发送一个请求到JSP, 使用XML返回餐厅的数据 .
- 打开 restaurantlist.jsp 文件 [ webapp_root ]/restaurant 并且使自己了解这个输出餐厅数据的 JSP .
- 在[ webapp_root ]/restaurant . 建立一个新文件 restaurant1.mxml .
- 编辑 restaurant1.mxml, 和键入以下代码 :
<?xml
version="1.0"
encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.macromedia.com/2003/mxml">
</mx:Application>
- 定义 HTTPService 如下 , 以便 application 能查询由 jsp 生成的 XML 数据 .
<mx:HTTPService
id="srv"
url="restaurantlist.jsp"/>
- 添加一个 Button 标签 Get Data . 指定点击事件句柄以便发送 HTTP 请求到已定义的 HTTPService 上面 .
<mx:Button
label="Get
Data"
click="srv.send()"/>
- 添加一个 DataGrid 组件并把它绑定到 HTTPService 的请求结果 .
<mx:DataGrid
id="dg"
dataProvider="{srv.result.list.restaurant}"
widthFlex="1"
heightFlex="1"/>
注: 注意那 srv.result
指向HTTP 请求的回应, 当 list
并且 restaurant
对应于XML文件的节点(参见restaurantlist.jsp) .
7. 测试程序: http://localhost:8700/flex/restaurant/restaurant1.mxml
如果您没有修改HTTPService的whitelist, 将出现以下错误:
这是因为Flex的默认安装后就有很高的安全级别 .您必须编辑HTTPservice的whitelist才能在application server中访问Java class, 修改步骤如下 .
- 编辑 [ webapp_root ]/WEB-INF/flex 目录下的 flex-config.xml .
- 找出
<http-service-proxy>条目
10. 在whitelist-unnamed-URL中添加 http://{localserver}/*
.
<http-service-proxy>
<!--
Other
entries
-->
<whitelist>
<unnamed>
<url>http://{localserver}/*</url>
</unnamed>
这样设置后, client application 可以访问服务器上的任何一URL .
11. 再测试程序 .
http://localhost:8700/flex/restaurant/restaurant1.mxml
- 修改 DataGrid 标记只显示显示 name, city, phone 三列 .
<mx:DataGrid
id="dg"
dataProvider="{srv.result.list.restaurant}"
widthFlex="1"
heightFlex="1">
<mx:columns>
<mx:Array>
<mx:DataGridColumn
columnName="name"
headerText="Name"/>
<mx:DataGridColumn
columnName="city"
headerText="City"/>
<mx:DataGridColumn
columnName="phone"
headerText="Phone"/>
</mx:Array>
</mx:columns>
</mx:DataGrid>
- 最后 , 改进用户界面 , 把 DataGrid 和 Button 放到 Panel 中 . 确定您添加 Button 到 Panel 的 ControlBar 中 .
<mx:Panel
title="Restaurant
List">
<!--
DataGrid
Here
-->
<mx:ControlBar>
<mx:Button
label="Get
Data"
click="srv.send()"/>
</mx:ControlBar>
</mx:Panel>
- 再测试程序 . 注意:如果您改变浏览器窗口的大小 , 您的 Flex 程序也跟着改变大小 .
实验2: 使用RemoteObject
使用RemoteObject, 您的client application可以在应用服务器里调用Java对象的method,并能接收method的返回值 .返回值可以是value of primitive data type, an object, a collection of objects,等等 .
在这个模块里, 您将修改restaurant application使用RemoteObject替代HTTPService查询餐厅名单 .您使用 您的应用服务器里的RestaurantService类的 getRestaurantList()
方法 . getRestaurantList()
方法将返回一个restaurant对象 .
步骤1: 审查服务器组件
- 打开 [ webapp_root ]/WEB-INF/classes/samples/restaurant 中 RestaurantService.Java 并且寻找
getRestaurantList()
方法 . 注意 , 方法返回 Restaurant 对象的一个数组 . - 打开 [ webapp_root ]/WEB-INF/classes/samples/restaurant下的 Restaurant.java .并了解这个类的一些属性和方法 .
步骤2: 使用RemoteObject
- 复制一个 restaurant1.mxml 改名为 restaurant2.mxml .
- 编辑 restaurant2.mxml .
3. 删除 HTTPService
标签,加入 RemoteObject
标签 . Remote class是 samples.restaurant.RestaurantService
并且使用方法 getRestaurantList()
返回餐厅的数据.
<mx:RemoteObject
id="srv"
source="samples.restaurant.RestaurantService">
<mx:method
name="getRestaurantList"/>
</mx:RemoteObject>
4. 改变按钮Get Data的触发事件为:调用RestaurantService类的 getRestaurantList()+
.
<mx:Button
label="Get
Data"
click="srv.getRestaurantList()"/>
5. 改变 dataProvider
的参数为 DataGrid
. 并把RestaurantService类的 getRestaurantList()
方法的结果绑定到 DataGrid
上 .
<mx:DataGrid
id="dg"
dataProvider="{srv.getRestaurantList.result}"
widthFlex="1"
heightFlex="1">
注: 每当您的程序调用一个远程方法,Flex建立结果集 . 结果集是指定方法的返回值 .
6. 测试应用: http://localhost:8700/flex/restaurant/restaurant2.mxml .
如果您没有修改RemoteObject的whitelist, 将出现以下错误:
- 编辑 [ webapp_root ]/WEB-INF/flex 目录下的 flex-config.xml .
- 找出
<remote-objects>
条目
9. 在whitelist-unnamed-URL中添加 samples.*
包 .
<remote-objects>
<!--
Other
entries
-->
<whitelist>
<unnamed>
<source>samples.*</source>
</unnamed>
这将允许客户应用访问任一类在样品包裹 .
这样设置后, client application 可以访问服务器上sample包下的所有类 .
- 再测试程序 : http://localhost:8700/flex/restaurant/restaurant2.mxml
实验3: 使用WebService
使用WebService组件, 您的client application可以在应用服务器里和网络的所有地方调用web services的mothod, 并能接收method的返回值 .返回值可以是value of primitive data type, an object, a collection of objects,等等 .
在这个实验中,修改restaurant application使用WebService 代替RemoteObject 查询餐厅数据 .
第一步: 把RestaurantService类作为Web Service
Flex中集成了Apache web services engine的Axis, 在没有提供web services的application server中更容易把Java 类作为web services .在这个部分, 您将使用Axis engine把RestaurantService类放到上一个模块中 .
注: 使用Flex WebService
标签, 您能连接到任何已经发布的web service .
发布RestaurantService类作为web service, 步骤如下:
- 编辑 [webapp_root ]/WEB-INF/flex 目录下 flex-config.wsdd .
2. 发布 RestaurantService
类名字为 RestaurantWS
的web service,使用以下 <service>
声明 .
<service
name="RestaurantWS"
provider="java:RPC">
<parameter
name="methodName"
value="*"/>
<parameter
name="className"
value="samples.restaurant.RestaurantService"/>
<beanMapping
languageSpecificType="java:samples.restaurant.Restaurant"
qname="ns1:Restaurant"
xmlns:ns1="http://www.macromedia.com/samples"/>
</service>
- 重启服务 .
- 测试 web service: 确定 web service 被正确的定义后,在浏览器中正确输入以下 URL:
http://localhost:8700/flex/flex-ws/RestaurantWS?wsdl .
第二步: 使用web service
- 复制 restaurant2.mxml 并改名为 restaurant3.mxml .
- 编辑 restaurant3.mxml .
3. 删除 RemoteObject标签
,并添加 WebService标签并
指向第一步建立的web server: RestaurantWS
.
<mx:WebService
id="srv"
wsdl="@ContextRoot()/flex-ws/RestaurantWS?wsdl">
<mx:operation
name="getRestaurantList"/>
</mx:WebService>
4. 测试应用: http://localhost:8700/flex/restaurant/restaurant3.mxml .
如果您没有修改WebService的whitelist, 将出现以下错误:
- 编辑 [ webapp_root]/WEB-INF/flex 目录下的 flex-config.xml .
- 找到
<web-service-proxy>
条目 - 添加
http://localhost:8700/* 到
whitelist 的 unnamed 中 .
<web-service-proxy>
<!--
Other
entries
-->
<whitelist>
<unnamed>
<url>http://localhost:8700/*</url>
</unnamed>
这样设置后, client application可以访问由Axis engine发布的所有web service .
- 再测试程序 : http://localhost:8700/flex/restaurant/restaurant3 .mxml .
数据服务: 总结
在不同服务端下,为了使你client application无缝的访问后台数据,Flex提供不同的数据存取方法 .
最佳的实践
如果您性能和数据量有要求, 在此建议您使用 RemoteObject
与 Action Message Format (AMF) (binary ) 内码 .
实验4: 使用 <mx:Model>
使用以下步使用 <mx:Model>
标签 .
- 复制 restaurant2.mxml 并改名 restaurant4.mxml .
注: 确定您拷贝的是restaurant2.mxml (使用RemoteObject的application版本) .
- 编辑 restaurant4 .mxml .
3. 添加一个Model标签在 RemoteObject标签后面
. 把RemoteObject的 getRestaurantList()
绑定到Model中 .
<mx:Model
id="restaurantList">{srv.getRestaurantList.result}</mx:Model>
4. 改变DataGrid 的 dataProvider
参数 . 绑定DataGrid到restaurantList Model上 .
<mx:DataGrid
id="dg"
dataProvider="{restaurantList}"
widthFlex="1"
heightFlex="1">
<mx:columns>
<mx:Array>
<mx:DataGridColumn
columnName="name"
headerText="Name"/>
<mx:DataGridColumn
columnName="city"
headerText="City"/>
<mx:DataGridColumn
columnName="phone"
headerText="Phone"/>
</mx:Array>
</mx:columns>
</mx:DataGrid>
- 测试程序 : http://localhost:8700/flex/restaurant/restaurant4.mxml
实验5: 使用可变的参考
Flex的所有数据服务都是以异步 方式运行 . 换句话说, 服务请求不阻拦您的application: 在您请求服务之后, application继续执行并不等待反应 . 当服务返回, 它触发 结果 事件句柄和您自己编写的处理方法 .
在这个实验, 您定义了一个restaurantList 实例变量, 并且您使用 结果 事件句柄 getRestaurantList()
方法分配, 服务返回的的餐厅数据变成了变量 .
使用以下步添加参考可变物 .
- 复制 restaurant4 .mxml 对 restaurant5 .mxml .
- 编辑 restaurant5 .mxml .
- 删除
模型
标记 .
4. 宣称实例变量被命名restaurantList .
5. <mx:Script>
6. var restaurantList:对象;
</mx:Script>
7. 添加a 结果
事件经理对 getRestaurantList
方法, 和分配 restaurantList
可变物对方法祈求的结果 .
8. <mx:RemoteObject id="srv" source="samples .餐厅 .RestaurantService">
9. <mx:方法name="getRestaurantList" result="restaurantList=event .result"/>
</mx:RemoteObject>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant5 .mxml .
使用命名的Services
当前的餐厅应用的其它局限是, 数据服务资源是硬编码在客户 . 例如, 在应用的HTTPService 版本, JSP 的URL 硬编码; 在WebService 版本, WSDL 文件是硬编码; 并且在RemoteObject 版本完全修饰的分类名硬编码 . 这不是一个最佳方案, 因为资源名字和地点可能改变 .
在这个部分, 您将使用逻辑名在客户应用提到数据服务 . 您使用部署形容标志(flex-config .xml 文件) 映射这些逻辑名对实际资源名字 .
最佳的实践:
不坚硬代码数据服务资源名字在客户应用 . 改为使用名为服务 .
实验室6: 使用命名的RemoteObject
步骤1: 定义命名的Service
- 编辑 flex-config .xml 在 [ webapp_root ]/WEB-INF/flex 目录 .
- 找出
<remote-objects>
词条 . - 添加以下名为服务来 whitelist .
4. <named>
5. <object name="RestaurantRO">
6. <source>samples .餐厅 .RestaurantService</source>
7. <type>stateless-class</type>
8. <use 风俗authentication>false</use 风俗authentication>
9. <allow 无提名access>false</allow 无提名access>
10. </object>
</named>
步骤2: 使用命名的Service
- 复制 restaurant5 .mxml 对 restaurant6 .mxml .
- 编辑 restaurant6 .mxml .
- 修改
RemoteObject
标记访问 Java 组使用逻辑名被定义在部署形容标志 .
4. <mx:RemoteObject id="srv" named="RestaurantRO">
5. <mx:方法name="getRestaurantList" result="restaurantList=event .result"/>
</mx:RemoteObject>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant6 .mxml
建立一个习惯组分
在这个模块里, 您建立一个习惯组分被命名RestaurantDetail . 这个组分显示餐厅的细节: 名字, 地址, 电话号码, 社论回顾, 图象, 等等 . 这是一个看法组分在您的客户边MVC 建筑学 . 您使用RestaurantDetail 组分的事例在您的主要应用显示餐厅的细节被选择在DataGrid .
在这个模块的完成, 应用将看起来象图8 .
实验室7: 建立RestaurantDetail 组分
步骤1: 建立RestaurantDetail 组分
- 建立一个新文件被命名 RestaurantDetail .mxml [ webapp_root ]/restaurant .
2. 编辑RestaurantDetail .mxml 和键入以下代码定义延伸HBox 容器的类 .
3. <?xml version="1 .0"encoding="utf-8 "?>
4. <mx:HBox xmlns:mx="http://www .macromedia .com/2003/mxml "marginTop="8 "marginLeft="8 "marginRight="8 "marginBottom="8">
</mx:HBox>
注: 当您建立一个MXML 文件, 您建立类 . 您的MXML 文件根结表明您扩大的类 . 在这种情况下, RestaurantDetail 延伸HBox 容器 . HBox 容器水平地计划二个组分:
-
- 左组分是显示餐厅的 VBox 容器 ( 名字、地址 , 电话号码的细节 , 等等 )
- 正确的组分是餐厅的图象 .
5. 定义一个实例变量被命名 dataObject
:
6. <mx:Script>
7. var dataObject:对象;
</mx:Script>
dataObject
事例代表餐厅对象以抽象方式 . 您做协会在这参考和实际餐厅对象之间在主要应用文件 .注意, RestaurantDetail 没有任何附庸或参考在其它组分或在根应用文件 . 这使RestaurantDetail 非常可再用 .
最佳的实践:
组分宽松联结是被证明的最佳的实践在面向对象的发展 . 宽松联结是避免相互依赖性在类之间尽量的编程技术 .宽松联结添加您的组分的可再用性在和横跨您的应用过程中 . 基本思想是组分更知道关于其它组分, 较不可再用的组分是 . 换句话说, 如果组分A 有强的参考(被键入的可变物) 在组分B, 您能只重复利用组分A 与组分B 一起 . 这附庸一般是不受欢迎的 .
8. 添加一个VBox 容器以适当的组分显示餐厅的细节 . 束缚用户界面组分对对应的属性 dataObject
实例变量 .
9. <mx:VBox widthFlex="1" verticalGap="0">
10. <mx:标签text="{dataObject .名字} "fontSize="16 "styleName="title"/>
11. <mx:标签text="{dataObject .address}"/>
12. <mx:标签text="{dataObject .city}"/>
13. <mx:标签text="{dataObject .phone}"/>
14. <mx:文本text="{dataObject .回顾} "widthFlex="1 "heightFlex="1"/>
</mx:VBox>
15. 添加 图象
标记显示餐厅的图象 .
<mx:图象source="images/{dataObject .图象} "width="200"/>
步骤2: 使用RestaurantDetail 组分在主要应用
- 复制 restaurant6 .mxml 对 restaurant7 .mxml .
- 打开 restaurant7 .mxml .
3. 添加 xmlns = "*"
对 应用
标记宣称名空间为组分没有前缀 .
<mx:应用xmlns:mx="http://www .macromedia .com/2003/mxml "xmlns="*">
4. 添加a 样式
标记附有餐厅 .css 样式表对您的应用 .
<mx:样式source="restaurant .css"/>
- 添加一个 HBox 容器在 " 餐厅名单 " 盘区附近 .
- 添加第二个盘区题为的细节在 HBox 容器里面 , 和在 " 餐厅名单 " 盘区以后 .
7. 添加a RestaurantDetail
标记在细节盘区 . 做 dataObject
归因于点餐厅被选择在DataGrid .
8. <mx:盘区title="Details" widthFlex="1" heightFlex="1">
9. <RestaurantDetail dataObject="{dg .selectedItem}"/>
</mx:Panel>
10. 自动地检索数据当应用开始, 去除ControlBar 在"餐厅名单" 盘区, 和祈求 getRestaurantList()
方法在 初始化
事件 应用
标记 .
<mx:应用xmlns:mx="http://www .macromedia .com/2003/mxml "xmlns =" * "initialize="srv .getRestaurantList()">
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant7 .mxml
实验室8: 建立ReviewList 组分
在这个模块里, 您建立一个组分被命名ReviewList . 这个组分负责对显示顾客回顾名单为选择的餐厅 . 在这个模块的完成, 应用将看起来象图9 .
步骤1: 建立ReviewList 组分
- 建立一个新文件被命名 ReviewList .mxml [ webapp_root ]/restaurant
2. 编辑ReviewList .mxml, 和键入以下代码定义延伸VBox 容器的类 .
3. <?xml version="1 .0"encoding="utf-8 "?>
4. <mx:VBox xmlns:mx="http://www .macromedia .com/2003/mxml "marginTop="8 "marginLeft="8 "marginRight="8 "marginBottom="8">
</mx:VBox>
5. 定义一个实例变量被命名 名单
. 名单可变物是在的参考餐厅回顾 . 协会在这参考和实际回顾之间将被做在主要应用文件 .
6. <mx:Script>
7. var 名单:对象;
</mx:Script>
- 添加 DataGrid 和束缚它对名单参考 . 显示 reviewDate 、评论者、标题 , 和规定值专栏 .
9. <mx:DataGrid id="dg" dataProvider="{list}" widthFlex="1">
10. <mx:columns>
11. <mx:Array>
12. <mx:DataGridColumn columnName="reviewDate" headerText="Date"/>
13. <mx:DataGridColumn columnName="reviewer" headerText="Reviewer"/>
14. <mx:DataGridColumn columnName="title" headerText="Title"/>
15. <mx:DataGridColumn columnName="rating 的" headerText="Rating"/>
16. </mx:Array>
17. </mx:columns>
</mx:DataGrid>
18. 添加适当的组分显示回顾的细节被选择在DataGrid . 束缚这些组分对 selectedItem
在DataGrid 自动地显示选择的项目的细节 .
19. <mx:HBox verticalAlign="middle">
20. <mx:VBox borderStyle="solid" horizontalAlign="center" verticalGap="0" width="80" marginTop="4" marginBottom="4">
21. <mx:标签text="Rating:"/>
22. <mx:标签text="{dg .selectedItem .rating}/10 "styleName="title"/>
23. </mx:VBox>
24. <mx:VBox verticalGap="0">
25. <mx:标签text="Reviewed:{dg .selectedItem .reviewer}"/>
26. <mx:标签text="Reviewed:{dg .selectedItem .reviewDate}"/>
27. </mx:VBox>
28. </mx:HBox>
<mx:文本text="{dg .selectedItem .reviewText} "widthFlex="1 "heightFlex="1"/>
步骤2: 使用ReviewList 组分在主要应用
- 复制 restaurant7 .mxml 对 restaurant8 .mxml .
- 打开 restaurant8 .mxml .
3. 宣称一个reviewList 实例变量在里面 <mx:Script>
标记 .
4. <mx:Script>
5. var restaurantList:对象;
6. var reviewList:对象;
</mx:Script>
- ( 任意 ) 开放 RestaurantService .Java [ webapp_root ]/WEB-INF/classes/samples/restaurant 并且使自己熟悉
getReviewList()
方法 .
8. 在restaurant8 .mxml, 添加 getReviewList()
方法对RemoteObject 声明 . 编码 结果
事件经理分配 reviewList
可变物对回顾返回了由方法 .
9. <mx:RemoteObject id="srv" source="samples .餐厅 .RestaurantService">
10. <mx:方法name="getRestaurantList" result="restaurantList=event .result"/>
11. <mx:方法name="getReviewList" result="reviewList=event .result"/>
</mx:RemoteObject>
12. 编码a 变动
事件经理为DataGrid: 检索回顾名单为选择的餐厅每次选择的餐厅改变 .
<mx:DataGrid id="dg" dataProvider="{restaurantList}" widthFlex="1" heightFlex="1" change="srv .getReviewList(dg .selectedItem .restaurantId)">
13. 包裹一个TabNavigator 容器在附近 RestaurantDetail
标记 . 添加一个一般信息标签来RestaurantDetail .
14. <mx:TabNavigator>
15. <RestaurantDetail label="General 信息" dataObject="{dg .selectedItem}"/>
</mx:TabNavigator>
16. 添加 ReviewList
标记作为第二个制表符在TabNavigator . 束缚 名单
物产对 reviewList
实例变量 .
17. <mx:TabNavigator>
18. <RestaurantDetail label="General 信息" dataObject="{dg .selectedItem}"/>
19. <ReviewList label="Reviews" list="{reviewList}"/>
</mx:TabNavigator>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant8 .mxml
实验室9: 建立回顾 .
步骤1: 审查服务器边组分
- 打开 RestaurantService .Java [ webapp_root ]/WEB-INF/classes/samples/restaurant 并且寻找
addReview
方法 . 注意addReview
方法采取 a回顾
对象作为论据 .
2. 打开回顾 .Java [ webapp_root ]/WEB-INF/classes/samples/restaurant 并且使自己熟悉类 .
-
- 注意 , 类是在
样品
.餐厅
包裹 . - 看属性由类暴露 .
- 注意 , 类是在
挑战将建立是可接受的作为输入参量的ActionScript 组当您祈求 addReview()
方法在RemoteObject 在客户端 . 换句话说, 您需要确信, 当送到服务器, 您的ActionScript 对象是deserialized 在a 样品
.餐厅
.回顾
对象 .
步骤2: 建立回顾组
1. 建立适当的目录结构主持属于的ActionScript 组 样品
.餐厅
包裹 .
-
- 建立一个样品目录 [ webapp_root ]/restaurant
- 建立一个餐厅目录 [ webapp_root ]/restaurant/samples
- 建立一个新文件被命名 Review .作为 [ webapp_root ]/restaurant/samples/restaurant
3. 编辑回顾 .作为和键入以下代码定义类被命名Review .
4. 类样品 .餐厅 .回顾{
}
5. 提供类以属性匹配属性可利用在类的Java 版本 .
6. var restaurantId:数字;
7. var reviewDate:串;
8. var 评论者:串;
9. var 规定值:数字;
10. var 标题:串;
var reviewText:串;
11. 添加 _ remoteClass
归因于, deserializer 使用计算哪Java 组使用 .
var _ remoteClass:串;
- 提供类以建设者过去常常初始化 _ remoteClass 易变 .
13. 作用Review() {
14. _ remoteClass="samples .餐厅 .回顾";
}
实验室10: 建立MyReview .mxml
在这个模块里, 您建立一个习惯组分被命名 MyReview
. 这个组分使用户输入他/她自己的回顾为餐厅 .
在这个模块的完成, 应用将看起来象这:
步骤1: 建立MyReview 组分
在这第一步, 您建立用户界面为MyReview 组分 . 您添加逻辑处理回顾数据在步骤3 .
- 建立一个新文件被命名 MyReview .mxml [ webapp_root ]/restaurant
- 编辑 MyReview .mxml, 和键入以下代码定义延伸 VBox 容器的类 .
3. <?xml version="1 .0"encoding="utf-8 "?>
4. <mx:VBox xmlns:mx="http://www .macromedia .com/2003/mxml "marginTop="8 "marginLeft="8 "marginRight="8 "marginBottom="8">
</mx:VBox>
- 定义一个实例变量被命名
restaurantId
. 价值为这可变物将由主要应用提供 ( 参见 步骤 2 ).
6. <mx:Script>
7. var restaurantId:数字;
</mx:Script>
- 计划适当的用户界面组分要求夺取顾客的回顾 .
9. <mx:Form>
10. <mx:FormItem label="Your Name">
11. <mx:TextInput id="reviewer"/>
12. </mx:FormItem>
13. <mx:FormItem label="Title">
14. <mx:TextInput id="title"/>
15. </mx:FormItem>
16. <mx:FormItem label="Rating">
17. <mx:NumericStepper id="rating 的" minimum="0" maximum="10"/>
18. </mx:FormItem>
19. </mx:Form>
20. <mx:TextArea id="reviewText" widthFlex="1" heightFlex="1"/>
<mx:按钮label="Post 我的Review"/>
步骤2: 添加MyReview 来主要应用
- 复制 restaurant8 .mxml 对 restaurant9 .mxml .
- 打开 restaurant9 .mxml .
- 添加
MyReview
标记作为第三个制表符在 TabNavigator 容器 , 提供价值为restaurandId
.
4. <mx:TabNavigator>
5. <RestaurantDetail label="General 信息" dataObject="{dg .selectedItem}"/>
6. <ReviewList label="Reviews" list="{reviewList}"/>
7. <MyReview label="MyReview" restaurantId="{dg .selectedItem .restaurantId}"/>
</mx:TabNavigator>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant9 .mxml
步骤3: 完成MyReview
- 打开 MyReview .mxml .
2. 定义一次习惯事件被命名 reviewAdded
.
3. <mx:Metadata>
4. [ Event("reviewAdded") ]
</mx:Metadata>
5. 在里面 <mx:Script>
标记, 定义一个作用被命名 addReview()
. 在这个作用, 您:
-
- 建立事例
回顾
类 . - 居住于这个事例以价值由用户键入 .
- 派遣
reviewAdded
事件 , 通过回顾对象作为事件对象一部分 .
- 建立事例
o 作用addReview() {
o var r = 新样品 .餐厅 .Review();
o r .restaurantId=restaurantId;
o r .reviewer=reviewer .文本;
o r .title=title .文本;
o r .rating=rating .价值;
o r .reviewText=reviewText .文本;
o dispatchEvent({type:"reviewAdded", 回顾:r});
}
6. 提供岗位我的回顾按钮以祈求的点击事件经理 addReview()
方法 .
<mx:按钮label="Post 我的回顾" click="addReview()"/>
步骤3: 送新回顾到服务器
1. 添加 addReview()
方法对 RemoteObject
声明
2. <mx:RemoteObject id="srv" source="samples .餐厅 .RestaurantService">
3. <mx:方法name="getRestaurantList" result="restaurantList=event .result"/>
4. <mx:方法name="getReviewList" result="reviewList=event .result"/>
5. <mx:方法name="addReview"/>
</mx:RemoteObject>
- 添加一个事件经理来 MyReview 组分祈求
addReview()
方法在RemoteObject
当回顾添加 .
7. <MyReview label="MyReview" restaurantId="{dg .selectedItem .restaurantId} "
reviewAdded="srv .addReview(event .review)"/>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant9 .mxml
实验室11: 建立地图 .mxml
在这个模块里, 您建立一个习惯组分被命名 地图
. 这个组分允许用户选择餐厅由区域使用地图隐喻 .
在这个模块的完成, 应用将看起来象这:
步骤1: 建立MyReview 组分
在这第一步, 您建立用户界面为 MyReview
组分 . 您添加逻辑处理回顾数据 步骤3 .
- 建立一个新文件被命名 Map .mxml [ webapp_root ]/restaurant
2. 编辑地图 .mxml, 和键入以下代码 .
3. <?xml version="1 .0"encoding="utf-8 "?>
4. <mx:帆布xmlns:mx="http://www .macromedia .com/2003/mxml "xmlns =" * "
5. mouseMove="doMouseMove()">
6. <mx:Script>
7. var bIsDown:布尔= 假;
8. var lastX:数字;
9. var lastY:数字;
10. 作用doMouseDown() {
11. bIsDown = 配齐;
12. lastX = mouseX;
13. lastY = mouseY;
14. }
15. 作用doMouseUp() {
16. bIsDown = 假;
17. }
18. 作用doMouseMove() {
19. 如果(bIsDown) {
20. var deltaX = mouseX - lastX;
21. var deltaY = mouseY - lastY;
22.
23. 选择器 .x + = deltaX;
24. 选择器 .y + = deltaY;
25.
26. lastX = mouseX;
27. lastY = mouseY;
28. }
29. }
30.
31. </mx:Script>
32.
33. <mx:图象id="map" source="@Embed('boston .gif')"/>
34. <mx:图象id="selector" source="@Embed('frame .gif ')"
35. mouseDown="doMouseDown()"
36. mouseUp="doMouseUp()"/>
37.
</mx:Canvas>
步骤2: 添加地图来主要应用
- 复制 restaurant9 .mxml 对 restaurant10 .mxml .
- 打开 restaurant10 .mxml .
3. 添加地图标记在"餐厅名单" 盘区在DataGrid 之前 .
<Map/>
- 测试应用 : http://localhost:8700/flex/restaurant/restaurant10 .mxml
步骤3: 处理地图地区选择
- 打开地图 .mxml .
2. 定义一次习惯事件被命名 selectionChanged
.
3. <mx:Metadata>
4. [ Event("selectionChanged") ]
</mx:Metadata>
5. 派遣 selectionChanged
事件在 doMouseUp()
作用 . 作为事件对象的属性提供选择座标 .
6. 作用doMouseUp() {
7. bIsDown = 假;
8. dispatchEvent({type:"selectionChanged", x1:选择器 .x, x2:选择器 .x+selector .宽度, y1:选择器 .y, y2:选择器 .y+selector .高度});
}
步骤4: 检索餐厅名单为选择的区域
- 添加
getRestaurantListByArea()
方法对RemoteObject
声明
2. <mx:RemoteObject id="srv" source="samples .餐厅 .RestaurantService">
3. <mx:方法name="getRestaurantList" result="restaurantList=event .result"/>
4. <mx:方法name="getRestaurantListByArea" result="restaurantList=event .result"/>
5. <mx:方法name="getReviewList" result="reviewList=event .result"/>
6. <mx:方法name="addReview"/>
</mx:RemoteObject>
7. 添加和事件经理对 地图
组分祈求 getRestaurantListByArea()
方法在 RemoteObject
当用户选择一个新区域 .
<Map width="495" height="355" selectionChanged="srv .getRestaurantListByArea(event .x1, 事件 .x2, 事件 .y1, 事件 .y2)"/>
测试应用 : http://localhost:8700/flex/restaurant/restaurant10 .mxml