Cairngorm是轻量级的MVC框架,其对于MVC划分的很清楚,甚至可以说是过于严格。整个框架没有对View,Model和Controller进行关联,而是对Event和Command的映射。
基本需求
1. 定义服务Service
在business文件夹下建立Services.mxml来定义服务。
一个Services.mxml文件大概是这样:
<?xml version="1.0"encoding="utf-8"?>
<cairngorm:ServiceLocatorxmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cairngorm="com.adobe.cairngorm.business.*">
<mx:HttpServiceid="httpService"/>
<mx:RemoteObjectid="remoteObject"/>
<mx:WebServiceid="webService"/>
<mx:Producerid="producer"/>
<mx:Consumerid="consumer"/>
<mx:DataServiceid="dataService"/>
</cairngorm:ServiceLocator>
这个文件定义了与服务器通信所用到的组件,Flex提供了6种组件进行通信。
2. 创建模型Model
一般来说,模型Model是一个单例。这时需要自己写这个模型,模型只是用来存储数据。
在model文件夹下建立你自己的Model,模型可以实现Cairngorm框架中的接口IModelLocator,但是这个动作是多余的。
将模型中需要提供给视图View的数据设置成[Bindable],也可以将Model设置成[Bindable],这样模型变化后,视图会自动更新。
package domain.app.model{
//[Bindable]
public class CustomModel{
[Bindable]
public var username:String;
[Bindable]
public var data:*;'
protected static var instance::CustomModel;
public static function getInstance():CustomModel{
if(!instance) instance=new CustomModel;
return instance;
}
}
}
3. 绑定视图View到模型Model
在视图中需要变更的部分,绑定模型中的数据。例如在一个Label组件需要使用模型的的用户名。
<mx:Label text="Welcome,{CustomModel.getInstance().username}"/>
模型的属性username改变时,界面会自动更新。
4. 定义事件。
Cairngorm框架中的事件CairngormEvent继承自Event,它有一个新的功能,就是自己把自己发送出去。
比如应用需要登陆,那就应该创建一个登陆事件LoginEvent,保存在events文件夹中。
package domain.app.events{
import com.adobe.cairngorm.control.CairngormEvent;
public class LoginEvent extends CairngormEvent{
public static constLOGIN:String="<login">;
public var username:String;
public var password:String;
public function LoginEvent(username:String,password:String){
super(LOGIN);
this.username=username;
this.password=password;
}
}
}
5. 处理事件
创建一个Event后,应用程序需要监听到这个Event并作出相应的处理。例如我已经创建了一个LoginEvent,然后还需要
创建一个ICommand来处理这个Event。在command文件夹下新建文件LoginCommand
package domain.app.command{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import domain.app.events.LoginEvent;
import domain.app.model.CustomModel;
public class LoginCommand implements ICommand{
override public functionexecute(event:CairngormEvent):void{
var evt:LoginEvent = event as LoginEvent;
var username:String=evt.username;
var password:String=evt.password;
if(username="admin"&&password=="admin"){
CustomModel.getInstance().username=username;
}
}
}
}
在这个CustomModel中执行的是业务逻辑,然后再改变模型CustomModel中的数据。
6. 注册事件到命令Command
Cairngorm框架中有个前段控制器FrontController,它的作用是把Event映射到ICommand。这样某个事件发出后,相应的ICommand会执行。
需要做的是在controller文件夹中新建一个自定义Controller来继承FrontController。
package domain.app.controller{
import com.adobe.cairngorm.control.FrontController;
import domain.app.events.*;
import domain.app.command.*;
public class CustomController extends FrontController{
public function CustomController(){
initialize();
}
private function initialize():void {
addCommand(LoginEvent.LOGIN, LoginCommand);
}
}
}
这个CustomController将事件LoginEvent和LoginCommand注册在一起,那么LoginEvent发出后会创建一个LoginCommand来执行业务逻辑。
6. 初始化框架
框架的好处就是让整个程序体系变得透明,便于扩展和代码重用。现在整个Cairngorm框架的实施基本完成,现在需要把它整合到Flex应用当中去。
在程序的入口,即程序的Default Application中实例化Controller。
<?xml version="1.0"encoding="utf-8"?>
<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:service="domain.app.business.*"
xmlns:controller="domain.app.controller.*">
<controller:CustomController id="controller"/>
</mx:Application>
7. 发出事件
下面需要监听程序中的用户交互事件,然后以CairngormEvent的形式发送出去。
假如程序中有一个登陆按钮,点击之后执行登陆操作。
private function doLogin():void{
var username:String=usernameFormItem.text;
var password:String=passwordFormItem.text;
new LoginEvent(username,password).dispatch();
}
在界面上做的是发出事件,而且只是发出事件。
8. 服务代理
在实际应用中,登陆需要服务器来验证其用户名和密码的正确性,于是需要使用一个Delegate来进行服务器的交互。
在business文件夹下创建类文件ServiceDelegate。
package domain.app.business{
import mx.rpc.IResponder;
import mx.rpc.events.*;
import com.adobe.cairngorm.business.ServiceLocator;
import domain.app.business.Services;
public class ServiceDelegate{
private var service:remoteObject;
public function ServiceDelegate(responder:IResponder){
service=Services.getInstance().getRemoteObject("remoteService");
service.doLogin.addEventListener(ResultEvent.RESULT,responder.onResult);
service.doLogin.addEventListener(FaultEvent.FAULT,responder.onFault);
}
public function doLogin(username:String,password:String){
service.doLogin(username,password);
}
}
}
这个ServiceDelegate有个方法来验证登录动作,可以通过ServiceLocater来获取一个HTTPService、RemoteObject或者其它交互组件,这个组件定义在
business文件夹下Services.mxml文件中。
然后修改LoginCommand:
package domain.app.command{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import domain.app.events.LoginEvent;
import domain.app.model.CustomModel;
public class LoginCommand implementsICommand,IRespondor{
private var delegate:ServiceDelegate;
private var username:String;
override public functionexecute(event:CairngormEvent):void{
var evt:LoginEvent = event as LoginEvent;
this.username=evt.username;
var password:String=evt.password;
delegate=new ServiceDelegate(this);
delegate.doLogin(username,password);
}
public function result(result:Object):void{
CustomModel.getInstance().username=username;
}
public function fault(info:Object):void{
}
}
}
9. 其它
整体上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:LoginViewHelperid="loginViewHelper"/>
然后就可以在Command中使用这个ViewHelper。
varloginViewHelper:LoginViewHelper=ViewLocator.getInstance().getViewHelper("loginViewHelper")
as LoginViewHelper;
loginViewHelper.doSomething();
10. 框架图
基本需求
1. 定义服务Service
在business文件夹下建立Services.mxml来定义服务。
一个Services.mxml文件大概是这样:
<?xml version="1.0"encoding="utf-8"?>
<cairngorm:ServiceLocatorxmlns:mx="http://www.adobe.com/2006/mxml"
</cairngorm:ServiceLocator>
这个文件定义了与服务器通信所用到的组件,Flex提供了6种组件进行通信。
2. 创建模型Model
一般来说,模型Model是一个单例。这时需要自己写这个模型,模型只是用来存储数据。
在model文件夹下建立你自己的Model,模型可以实现Cairngorm框架中的接口IModelLocator,但是这个动作是多余的。
将模型中需要提供给视图View的数据设置成[Bindable],也可以将Model设置成[Bindable],这样模型变化后,视图会自动更新。
package domain.app.model{
}
3. 绑定视图View到模型Model
在视图中需要变更的部分,绑定模型中的数据。例如在一个Label组件需要使用模型的的用户名。
<mx:Label text="Welcome,{CustomModel.getInstance().username}"/>
模型的属性username改变时,界面会自动更新。
4. 定义事件。
Cairngorm框架中的事件CairngormEvent继承自Event,它有一个新的功能,就是自己把自己发送出去。
比如应用需要登陆,那就应该创建一个登陆事件LoginEvent,保存在events文件夹中。
package domain.app.events{
}
5. 处理事件
创建一个Event后,应用程序需要监听到这个Event并作出相应的处理。例如我已经创建了一个LoginEvent,然后还需要
创建一个ICommand来处理这个Event。在command文件夹下新建文件LoginCommand
package domain.app.command{
}
在这个CustomModel中执行的是业务逻辑,然后再改变模型CustomModel中的数据。
6. 注册事件到命令Command
Cairngorm框架中有个前段控制器FrontController,它的作用是把Event映射到ICommand。这样某个事件发出后,相应的ICommand会执行。
需要做的是在controller文件夹中新建一个自定义Controller来继承FrontController。
package domain.app.controller{
}
这个CustomController将事件LoginEvent和LoginCommand注册在一起,那么LoginEvent发出后会创建一个LoginCommand来执行业务逻辑。
6. 初始化框架
框架的好处就是让整个程序体系变得透明,便于扩展和代码重用。现在整个Cairngorm框架的实施基本完成,现在需要把它整合到Flex应用当中去。
在程序的入口,即程序的Default Application中实例化Controller。
<?xml version="1.0"encoding="utf-8"?>
<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"
</mx:Application>
7. 发出事件
下面需要监听程序中的用户交互事件,然后以CairngormEvent的形式发送出去。
假如程序中有一个登陆按钮,点击之后执行登陆操作。
private function doLogin():void{
}
在界面上做的是发出事件,而且只是发出事件。
8. 服务代理
在实际应用中,登陆需要服务器来验证其用户名和密码的正确性,于是需要使用一个Delegate来进行服务器的交互。
在business文件夹下创建类文件ServiceDelegate。
package domain.app.business{
}
这个ServiceDelegate有个方法来验证登录动作,可以通过ServiceLocater来获取一个HTTPService、RemoteObject或者其它交互组件,这个组件定义在
business文件夹下Services.mxml文件中。
然后修改LoginCommand:
package domain.app.command{
}
9. 其它
整体上Cairngorm的框架就是这样,你可能发现在ICommand处理一个CairngormEvent时,没有办法获得一个View的引用。没错,这就是它的MVC机制,因为你不应该把业务逻辑和视图View挂钩,但是有时候必须要和View挂钩,那就得用到框架中的ViewHelper和ViewLocator这两个类了。
ViewHelper类实现接口IMXMLObject,首先自定义一个ViewHelper,然后在视图中引用它。
package domain.app.view{
}
在视图中实例化这个ViewHelper
<helper:LoginViewHelperid="loginViewHelper"/>
然后就可以在Command中使用这个ViewHelper。
varloginViewHelper:LoginViewHelper=ViewLocator.getInstance().getViewHelper("loginViewHelper")
loginViewHelper.doSomething();
10. 框架图
