加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flex4系列教程之十一 – 整合PureMVC(剧终)

发布时间:2020-12-15 05:05:15 所属栏目:百科 来源:网络整理
导读:转载地址:http://www.perfect-peak.com/blog/2011/03/13/puremvc/ PureMVC? 概述 PureMVC 是什么? PureMVC 是一个定位于设计高性能 RIA 客户端的基于模式的框架。目前已经被移植到多种语言(AS2、AS3、C#、ColdFusion、Haxe、JavaScript、Java、Objective

转载地址:http://www.perfect-peak.com/blog/2011/03/13/puremvc/

PureMVC? 概述

  1. PureMVC 是什么?
    PureMVC 是一个定位于设计高性能 RIA 客户端的基于模式的框架。目前已经被移植到多种语言(AS2、AS3、C#、ColdFusion、Haxe、JavaScript、Java、Objective C、PHP、Python、Ruby)和平台,包括服务器端环境。
  2. PureMVC 原理图示

  3. PureMVC 的两个版本
    PureMVC 分为标准(Standard)和多核(MultiCore)两个版本。后者目的在于进行模块化编程。[PureMVC – Multicore vs Standard / Singlecore]介绍了两个版本的本质区别。
  4. PureMVC 教程
    PureMVC Framework Goals and Benefits
    PureMVC Framework Overview with UML
    PureMVC Implementation Idioms and Best Practices
    PureMVC Implementation Idioms and Best Practices 简体中文(感谢张泽远和 Tamt 的翻译工作)

开始整合

  1. 注意事项:
    以下内容基于“Flex4系列教程之九”中最后形成的 sampleApp 项目。
  2. 准备所需组件
    下载?PureMVC(AS3) 多核版,将解压后的 PureMVC_AS3_MultiCore_1_0_5.swc 拷贝到 flex_libs 文件夹。
  3. 在 flex_src 下创建以下文件夹
    employees
    employees/controller :放置 Command 类
    employees/model :放置 Proxy 类
    employees/view :放置 Mediator
    employees/view/components:放置视图文件(即 mxml 文件)
  4. 在继续之前,还是回顾一下 PureMVC 的原理吧
    记住一点:PureMVC 的通信并不采用 Flash 的 EventDispatcher/Event,而是使用观察者模式以一种松耦合的方式来实现的。

    所以要显示存储在数据库中的职员信息需经过以下过程:

    • View Component 触发一个 Event;
    • Mediator 监听到此 Event,发送通知;
    • 控制器依据通知找到对应的 Command;
    • Command 调用 Proxy(Proxy 又调用 Server 端对象),Proxy 依据执行结果发送相应通知;
    • Mediator 接收到上诉通知,随即把通知中附带的雇员信息赋值给 DataGrid 组件。
  5. 不难理解,我们之所以创建 employees 文件夹就是要把雇员信息相关机能放到此文件下。
    出于此目的我们把显示雇员信息的 DataGrid 组件从 sampleApp.mxml 中分离出来,命名为 EmployeesDataGrid,存储于 employees/view/components 下。

    <?xml version="1.0" encoding="utf-8"?>
    <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:s="library://ns.adobe.com/flex/spark"
              xmlns:mx="library://ns.adobe.com/flex/mx"
              width="400" x="32" y="25">
    
        <mx:DataGrid id="employeesList" width="400">
            <mx:columns>
                <mx:DataGridColumn headerText="Name"  dataField="name"/>
                <mx:DataGridColumn headerText="Age"   dataField="age"/>
                <mx:DataGridColumn headerText="Email" dataField="email"/>
            </mx:columns>
        </mx:DataGrid>
    </s:VGroup>
  6. 在 sampleApp 中引入 EmployeesDataGrid 组件
    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:view="employees.view.components.*"> <view:EmployeesDataGrid id="employeesDataGrid"/> </s:Application>
  7. 在 employees 下创建 ApplicationFacade,作为此应用程序的 Facade
    package employees { import org.puremvc.as3.multicore.patterns.facade.Facade; import employees.controller.*; public class ApplicationFacade extends Facade { public static const STARTUP:String = 'startup'; public function ApplicationFacade(key:String) { super(key); } public static function getInstance(key:String):ApplicationFacade { if (instanceMap[key] == null) instanceMap[key] = new ApplicationFacade(key); return instanceMap[key] as ApplicationFacade; } override protected function initializeController():void { super.initializeController(); registerCommand(STARTUP,StartupCommand); } public function startup(app:sampleApp):void { sendNotification(STARTUP,app); } } }

    [注:]看到上面的 StartupCommand 了吧,我们稍候创建它,该 Command 主要用于注册 Proxy 和 Mediator。

  8. 在主应用中初始化 Facade,并调用 startup 方法(应该能理解调用此方法的意图吧?)
    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:view="employees.view.components.*" initialize="facade.startup(this);"> <fx:Script> <![CDATA[ import employees.ApplicationFacade; public static const NAME:String = 'sampleApp'; private var facade:ApplicationFacade = ApplicationFacade.getInstance(NAME); ]]> </fx:Script> <view:EmployeesDataGrid id="employeesDataGrid"/> </s:Application>
  9. 是时候创建 StartupCommand 了
    package employees.controller { import org.puremvc.as3.multicore.patterns.command.SimpleCommand; import org.puremvc.as3.multicore.interfaces.INotification; public class StartupCommand extends SimpleCommand { override public function execute(note:INotification):void { // @TODO } } }
  10. 至此 pureMVC 已经整合完毕,是不是很简洁?:) 接下来实现雇员信息输出。
  11. 首先在 model 下创建 LoadEmployeesProxy,调用远程对象返回雇员信息
    package employees.model { import org.puremvc.as3.multicore.patterns.proxy.Proxy; import mx.rpc.remoting.RemoteObject; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; public class LoadEmployeesProxy extends Proxy { public static const NAME:String = 'LoadEmployeesProxy'; public static const LOAD_EMPLOYEES_SUCCESS:String = 'loadEmployeesSuccess'; public static const LOAD_EMPLOYEES_FAILED:String = 'loadEmployeesFailed'; private var employeeServiceRO:RemoteObject; public function LoadEmployeesProxy() { super(NAME); employeeServiceRO = new RemoteObject(); employeeServiceRO.destination = "employeeServiceDest"; employeeServiceRO.addEventListener(ResultEvent.RESULT,onResult); employeeServiceRO.addEventListener(FaultEvent.FAULT,onFault); } public function load():void { employeeServiceRO.getList(); } private function onResult(event:ResultEvent):void { sendNotification(LOAD_EMPLOYEES_SUCCESS,event.result); } private function onFault(event:FaultEvent):void { sendNotification(LOAD_EMPLOYEES_FAILED,event.fault.faultString); } } }
  12. 其次在 view 下创建管理 EmployeesDataGrid 的 Mediator — EmployeesDataGridMediator
    package employees.view { import org.puremvc.as3.multicore.patterns.mediator.Mediator; import org.puremvc.as3.multicore.interfaces.INotification; import flash.events.Event; import mx.controls.Alert; import employees.ApplicationFacade; import employees.model.LoadEmployeesProxy; import employees.view.components.EmployeesDataGrid; public class EmployeesDataGridMediator extends Mediator { public static const NAME:String = 'EmployeesListMediator'; public function EmployeesDataGridMediator(viewComponent:EmployeesDataGrid) { super(NAME,viewComponent); employeesDataGrid.addEventListener(EmployeesDataGrid.LOAD_EMPLOYEES,onGetEmployees); } protected function onGetEmployees(event:Event):void { sendNotification(ApplicationFacade.LOAD_EMPLOYEES); } override public function listNotificationInterests():Array { return [ LoadEmployeesProxy.LOAD_EMPLOYEES_SUCCESS,LoadEmployeesProxy.LOAD_EMPLOYEES_FAILED ]; } override public function handleNotification(note:INotification):void { switch (note.getName()) { case LoadEmployeesProxy.LOAD_EMPLOYEES_SUCCESS: employeesDataGrid.employeesList.dataProvider = note.getBody(); break; case LoadEmployeesProxy.LOAD_EMPLOYEES_FAILED: Alert.show(note.getBody().toString(),'Error'); break; } } protected function get employeesDataGrid():EmployeesDataGrid { return viewComponent as EmployeesDataGrid; } } }
  13. 把上面创建的 Proxy 和 Mediator 注册到 Model 和 View 中
    package employees.controller { import org.puremvc.as3.multicore.patterns.command.SimpleCommand; import org.puremvc.as3.multicore.interfaces.INotification; import employees.model.LoadEmployeesProxy; import employees.view.EmployeesDataGridMediator; public class StartupCommand extends SimpleCommand { override public function execute(note:INotification):void { facade.registerProxy(new LoadEmployeesProxy()); var app:sampleApp = note.getBody() as sampleApp; facade.registerMediator(new EmployeesDataGridMediator(app.employeesDataGrid)); } } }

    [注:]在注册 Mediator 的时候也就确定了它所管理的 Mxml 文件

  14. 在 controller 中创建 LoadEmployeesCommand,用于调用 LoadEmployeesProxy
    package employees.controller { import org.puremvc.as3.multicore.patterns.command.SimpleCommand; import org.puremvc.as3.multicore.interfaces.INotification; import employees.model.LoadEmployeesProxy; public class LoadEmployeesCommand extends SimpleCommand { override public function execute(note:INotification):void { var loadEmployeesProxy:LoadEmployeesProxy = facade.retrieveProxy(LoadEmployeesProxy.NAME) as LoadEmployeesProxy; loadEmployeesProxy.load(); } } }
  15. 把 LoadEmployeesCommand 与事件的对应关系追加到 ApplicationFacade 中
    package employees { import org.puremvc.as3.multicore.patterns.facade.Facade; import employees.controller.*; public class ApplicationFacade extends Facade { public static const STARTUP:String = 'startup'; public static const LOAD_EMPLOYEES:String = 'loadEmployees'; public function ApplicationFacade(key:String) { super(key); } public static function getInstance(key:String):ApplicationFacade { if (instanceMap[key] == null) instanceMap[key] = new ApplicationFacade(key); return instanceMap[key] as ApplicationFacade; } override protected function initializeController():void { super.initializeController(); registerCommand(STARTUP,StartupCommand); registerCommand(LOAD_EMPLOYEES,LOADEmployeesCommand); } public function startup(app:sampleApp):void { sendNotification(STARTUP,app); } } }
  16. 万事俱备,只需要在 EmployeesDataGrid 创建完毕时触发相应事件
    <?xml version="1.0" encoding="utf-8"?> <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" x="32" y="25" creationComplete="init();"> <fx:Metadata> [Event('loadEmployees')] </fx:Metadata> <fx:Script> <![CDATA[ public static const LOAD_EMPLOYEES:String = 'loadEmployees'; public function init():void { dispatchEvent(new Event(LOAD_EMPLOYEES,true)); } ]]> </fx:Script> <mx:DataGrid id="employeesList" width="400"> <mx:columns> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Age" dataField="age"/> <mx:DataGridColumn headerText="Email" dataField="email"/> </mx:columns> </mx:DataGrid> </s:VGroup>
  17. 运行试试吧 :)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读