Cairngorm中View层的交互3种方式

[转]Cairngorm中View层的交互3种方式

 

  Cairngorm中各层的含义与关系参见《Cairngorm框架——MVC基本理论》,这里探讨一下View层的交互问题。

  根据Cairngorm的原理,View层中的数据通过绑定ModelLocator中的属性实现自动更新,但有时我们想要的效果不仅仅是数据 自动更新这么简单,而且有可能会对View层界面进行操作,譬如切换状态、弹出提示窗口、弹出选择界面等,这些操作如果放在Command中处理的话,使 Controller层与View层耦合了,不利于MVC松散耦合的概念。

  举个简单例子

  Flex程序由两个界面组成:登陆界面和主界面,在Application中分别定义为login和main状态,默认为login状态。当login成功后,切换为main状态。

  按照Cairngorm的用户登陆Command如下:

01 import com.adobe.cairngorm.commands.ICommand;
02 import com.adobe.cairngorm.control.CairngormEvent;
03  
04 import mx.controls.Alert;
05 import mx.core.FlexGlobals;
06 import mx.rpc.IResponder;
07      
08 import spark.components.Application;
09      
10 public class UserLoginCommand implements ICommand, IResponder
11 {
12     public function execute(event:CairngormEvent):void
13     {
14         var e:UserLoginEvent = event as UserLoginEvent;
15         var delegate:SystemDelegate = new SystemDelegate(this);
16         delegate.userLogin(e.userName, e.password);
17     }
18          
19     public function result(data:Object):void
20     {
21         var app:Application = (FlexGlobals.topLevelApplication) as Application;
22         app.currentState = "main";
23     }
24          
25     public function fault(info:Object):void
26     {
27         Alert.show(info.toString());
28     }
29  
30 }

  这里,Command的代码中牵涉到Application的CurrentState了,且还有Alert.show方法,这些应该都是 View层做的事情。为了达到松散耦合的墓地,我们定义一用户登陆完成事件,在Command中执行完后派发,在View层中监听该事件并处理。

  定义用户登陆完成事件UserLoginCompleteEvent

01 import com.adobe.cairngorm.control.CairngormEvent;
02      
03 public class UserLoginCompleteEvent extends CairngormEvent
04 {
05     static public const EVENT_ID:String = "userLoginComplete";
06     public var success:Boolean = false;
07  
08     public function UserLoginCompleteEvent()
09     {
10         super(EVENT_ID);
11     }
12  
13 }

  Command代码修改为响应时向外派发UserLoginCompleteEvent事件

01 import com.adobe.cairngorm.commands.ICommand;
02 import com.adobe.cairngorm.control.CairngormEvent;
03 import com.adobe.cairngorm.control.CairngormEventDispatcher;
04  
05 import mx.rpc.IResponder;
06      
07 public class UserLoginCommand implements ICommand, IResponder
08 {
09     public function execute(event:CairngormEvent):void
10     {
11         var e:UserLoginEvent = event as UserLoginEvent;
12         var delegate:SystemDelegate = new SystemDelegate(this);
13         delegate.userLogin(e.userName, e.password);
14     }
15          
16     public function result(data:Object):void
17     {
18         complete(true, null);
19     }
20          
21     public function fault(info:Object):void
22     {
23         complete(false, info);
24     }
25  
26     private function complete(success:Boolean, data:Object):void
27     {
28         var e:UserLoginCompleteEvent = new UserLoginCompleteEvent();
29         e.success = success;
30         e.data = data;
31         CairngormEventDispatcher.getInstance().dispatchEvent(e);
32     }
33 }

  Application的creationComplete事件中监听UserLoginCompleteEvent事件

01 protected function creationCompleteHandler(event:FlexEvent):void
02 {
03     CairngormEventDispatcher.getInstance().addEventListener(UserLoginCompleteEvent.EVENT_ID, userLoginCompleteHandler);
04 }
05  
06 private function userLoginCompleteHandler(e:UserLoginCompleteEvent):void
07 {
08     if (e.success)
09         currentState = "desktop";
10     else
11         Alert.show(e.data.toString());
12 }

  值得注意的是,UserLoginCompleteEvent不需要在FrontController中注册,而且需要View层互动时才需要 使用对应逻辑的CompleteEvent,其他互动用Cairngorm提倡的Bindable Model Locator解决。

  虽然Cairngorm的代码量不少,但我个人觉得分层还是很明确的,特别是团队开发时只需要专注自己关心的部分就可以了。



方式3:==============================================>


来源:http://blog.sina.com.cn/s/blog_4cf1f6670100d7rd.html

整体上Cairngorm的框架就是这样,你可能发现在ICommand处理一个CairngormEvent时,没有办法获得一个View的引用。没 错,这就是它的MVC机制,因为你不应该把业务逻辑和视图View挂钩,但是有时候必须要和View挂钩,那就得用到框架中的ViewHelper和 ViewLocator这两个类了。

ViewHelper类实现接口IMXMLObject,首先自定义一个ViewHelper,然后在视图中引用它。
package domain.app.view{
 


 import com.adobe.cairngorm.view.ViewHelper;
 
 public class LoginViewHelper extends ViewHelper{
 
  public function doSomething(){
  //do something with the protected property view.
  }
 }
}

在视图中实例化这个ViewHelper
<helper:LoginViewHelper id="loginViewHelper"/>

然后就可以在Command中使用这个ViewHelper。
var loginViewHelper:LoginViewHelper=ViewLocator.getInstance().getViewHelper("loginViewHelper") 
  as LoginViewHelper;
loginViewHelper.doSomething();




据说还有一种方式:====================================================
通过单例 ModelLocator 和单例 ViewLocator 能访问到任何在其注册的 model 和 view

posted on 2011-07-30 23:17  一江春水  阅读(361)  评论(0)    收藏  举报

导航