上一篇 puremvc框架之Command 里,已经学习了如何利用Command来解耦View层与业务逻辑的依赖,但是仍然有二个问题:

1、ButtonMediator中发送消息时,仍然采用硬编码的方式,将消息内容写死在代码中:


1

2

3




​private​​​​function​​​​btnClick(e:MouseEvent):​​​​void​​​​{​​​​            ​​​​this​​​​.sendNotification(AppFacade.CHANGE_TEXT,​​​​"Hello PureMVC !"​​​​);​​​​        ​​​​}       ​




这显然不是一个好的设计,不够灵活

2、我们一直在说puremvc是一个mvc框架,至今为止 controller(即Command)、view(即Mediator)都已经出现过了,但是model层还是不见踪影,puremvc中的model层在哪里

在asp.net mvc中,model层通常是定义数据实体的部分,可以选用的技术有很多,比如linq to sql,linq to entity ,nhibernate之类,这个概念在puremvc中仍然是相通的,只不过换了个名字,我们称之为Proxy

先来定义一个AppProxy类吧(放到mvc.model包中),代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36




​package​​​​mvc.model​​​​{​​​​    ​​​​import​​​​org.puremvc.as3.interfaces.IProxy;​​​​    ​​​​import​​​​org.puremvc.as3.patterns.proxy.Proxy;​​​​    ​​​​import​​​​flash.events.IOErrorEvent;​​​​    ​​​​import​​​​flash.events.Event;​​​​    ​​​​import​​​​flash.net.URLLoader;​​​​    ​​​​import​​​​flash.net.URLRequest;​



​    ​​​​public​​​​class​​​​AppProxy ​​​​extends​​​​Proxy ​​​​implements​​​​IProxy​​​​    ​​​​{​​​​        ​​​​public​​​​static​​​​const​​​​NAME:​​​​String​​​​=​​​​"AppProxy"​​​​; ​​​​//名称常量​


​        ​​​​public​​​​function​​​​AppProxy(proxyName:​​​​String​​​​=​​​​null​​​​, data:​​​​Object​​​​=​​​​null​​​​)​​​​        ​​​​{​​​​            ​​​​super​​​​(NAME, data);​​​​//将本proxy的名称常量传入其中​​​​            ​​​​var​​​​_loader:URLLoader=​​​​new​​​​URLLoader;​​​​            ​​​​_loader.addEventListener(Event.COMPLETE, onComplete);​​​​            ​​​​_loader.addEventListener(IOErrorEvent.IO_ERROR, onError);​​​​            ​​​​_loader.load(​​​​new​​​​URLRequest(​​​​"data.xml"​​​​));​​​​        ​​​​}​


​        ​​​​private​​​​function​​​​onComplete(e:Event):​​​​void​​​​        ​​​​{​


​            ​​​​var​​​​_xml:XML=XML(e.target.data);​​​​            ​​​​setData(_xml); ​​​​//将xml内容保存进data​​​​        ​​​​}​


​        ​​​​private​​​​function​​​​onError(e:IOErrorEvent):​​​​void​​​​        ​​​​{​​​​            ​​​​trace​​​​(​​​​"数据获取失败!"​​​​);​​​​        ​​​​}​​​​    ​​​​}​​​​}​



剪切
复制
粘贴
左边插入 列
右边插入 列
上方插入 行
下方插入 行
合并单元格
拆分单元格
删除选中列
删除选中行
删除表格
清空内容


这里,我们用xml做为数据源来提供数据,data.xml放到根目录下,内容如下:



1

2

3

4




​<?​​​​xml​​​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"UTF-8"​​​​?> ​​​​<​​​​message​​​​> ​​​​        ​​​​<​​​​msg​​​​>Hello World!</​​​​msg​​​​>​​​​</​​​​message​​​​> ​




ok,这一步做好后,老问题又来了:如何让它跟puremvc环境中的facade实例挂上勾?类似上一篇的处理,还是放到AppCommand中来处理


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31




​package​​​​mvc.controller​​​​{​​​​    ​​​​import​​​​mvc.AppFacade;​​​​    ​​​​import​​​​mvc.model.AppProxy;​​​​    ​​​​import​​​​mvc.view.ButtonMediator;​​​​    ​​​​import​​​​mvc.view.TextMediator;​​​​    ​​ ​​    ​​​​import​​​​org.puremvc.as3.interfaces.INotification;​​​​    ​​​​import​​​​org.puremvc.as3.patterns.command.SimpleCommand;​


​    ​​​​public​​​​class​​​​AppCommand ​​​​extends​​​​SimpleCommand​​​​    ​​​​{​​​​        ​​​​public​​​​function​​​​AppCommand()​​​​        ​​​​{​​​​            ​​​​super​​​​();​​​​        ​​​​}​


​        ​​​​public​​​​override​​​​function​​​​execute(inote:INotification):​​​​void​​​​        ​​​​{​​​​            ​​​​var​​​​_main:main=inote.getBody() ​​​​as​​​​main;​​​​            ​​ ​​            ​​​​//注册proxy​​​​            ​​​​facade.registerProxy(​​​​new​​​​AppProxy());​​​​            ​​ ​​            ​​​​facade.registerMediator(​​​​new​​​​TextMediator(_main.txtResult));​​​​            ​​​​facade.registerMediator(​​​​new​​​​ButtonMediator(_main.btnSend));         ​​​​            ​​ ​​            ​​​​facade.registerCommand(AppFacade.CHANGE_TEXT,ChangeTextCommand);​​​​        ​​​​}​​​​    ​​​​}​​​​}​




注意加注释的部分facade.registerProxy(new AppProxy());这样就ok了,这一步执行后,puremvc环境中就已经有data.xml的数据了

现在就可以把原来ButtonMediator中硬编码的部分去掉了,改成下面这样:


1

2

3

4




​private​​​​function​​​​btnClick(e:MouseEvent):​​​​void​​​​{​​​​        ​​​​//this.sendNotification(AppFacade.CHANGE_TEXT,"Hello PureMVC !");           ​​​​        ​​​​sendNotification(AppFacade.CHANGE_TEXT);​​​​    ​​​​}​




即:view层只发送消息(类型),通知puvrmvc环境--“CHANGE_TEXT消息我已经发出去了!”,至于数据在哪,谁去处理,关我P事!

OK,有人发了消息,自动就要有人处理,接下来折腾ChangeTextCommand.as


1

2

3

4

5

6

7

8




​public​​​​override​​​​function​​​​execute(notification:INotification):​​​​void​​​​{​​​​            ​​ ​​            ​​​​var​​​​_proxy:AppProxy=facade.retrieveProxy(AppProxy.NAME) ​​​​as​​​​AppProxy;            ​​​​            ​​​​var​​​​_xml:XML=XML(_proxy.getData());         ​​​​            ​​​​trace​​​​(_xml);            ​​​​            ​​​​(facade.retrieveMediator(TextMediator.NAME) ​​​​as​​​​TextMediator).txtInstance.text = _xml.msg;           ​​​​            ​​​​//(facade.retrieveMediator(TextMediator.NAME) as TextMediator).txtInstance.text = notification.getBody() as String;​​​​        ​​​​}​




这里,我们把原来的方法注释掉了,改成用Proxy的getData获取刚才data.xml中的数据,然后该数据赋值为TextMediator相关联的文本框.

至此,M(proxy)-V(mediator)-C(command)全都登场了,相互之间也实现了完全解耦!


最后再从头回顾一下主要的处理细节

1、man.mxml中通过 AppFacade.getInstance().startup(this) 启动puvemvc环境

2、而AppFacade又通过this.registerCommand(START_UP, AppCommand) 注册AppCommand

3、AppCommand中又通过


1

2

3

4




​facade.registerProxy(​​​​new​​​​AppProxy());           ​​​​facade.registerMediator(​​​​new​​​​TextMediator(_main.txtResult));​​​​facade.registerMediator(​​​​new​​​​ButtonMediator(_main.btnSend));     ​​​​facade.registerCommand(AppFacade.CHANGE_TEXT,ChangeTextCommand);​




把mediator、proxy以及消息CHANGE_TEXT相关的ChangeTextCommand给扯进来

4、然后ButtonMediator中又通过sendNotification(AppFacade.CHANGE_TEXT)来发送自己感兴趣的消息

5、最后CHANGE_TEXT消息被与之关联的ChangeTextCommand得到,并在execute方法中处理以更新UI界面。

源文件下载:​​http://cid-2959920b8267aaca.office.live.com/self.aspx/flex/PureMVC^_Proxy.fxp​​ (用FB4导入即可)