由 Daniel Yang 撰写 http://blog.ityao.com/archives/226
(替阿银开个头。写一个Hello world示例.)
Parsley是Flex/Flash/AIR的一个开发框架,使用AS3。
Spicelib是一个AS3的库,Parsley基于这个库,但是可以单独使用。
Parsley的功能有:
Flexible IOC Container: Supports configuration with AS3 Metadata, MXML, XML files, ActionScript
Dependency Injection: Injection by type or id – for constructors, methods or properties
Messaging Framework: Fully decoupled senders and receivers, can serve as a basis for MVC architectures
Flex View Wiring: Easily wire Flex components to objects declared in the container
Advanced container features: Asynchronously initializing objects, object lifecycle, modular configuration contexts
Integration with Flex Modules: Allows configuration to be loaded and unloaded alongside Flex Modules
Localization: Integrates with Flex ResourceManager for Flex Applications, contains its own Localization Framework for Flash Applications
Extensibility: Easily create your own configuration tags, a single implementation can be used as AS3 Metadata, MXML or XML tag
And much more…bla bla blah
Spicelib同时也提供:
Reflection API: A clean object-oriented API built around the describeType XML output
XML-to-Object Mapper: Flexible architecture for mapping from XML to AS3 classes – in both directions
Task Framework: Abstraction for asynchronous operations and sequential or concurrent execution
Logging: Logging Framework for Flash Applications
Step 1, 下载
http://www.spicefactory.org/parsley/download.ph
Step 2, 建立Flex项目
这个大家都会。在Flex Builder 3中建立一个ParsleyTest的项目。
我们在这个项目中,完成一个用户登录的示例。
Step 3, 引用
解压后,会有3个文件夹:
lib下,是你在开发的时候可能会用到的几个swc库文件。
src下,不言而喻。
release下,是我们这个教程需要的东西。当然,不是全部,我们这里只用到parsley-complete-flex-2.0.1.swc, spicelib-complete-flex-2.0.1.swc
官方说只用一个就可以了–那是不可能的。
为了方便,我们把这个文件移至ParsleyTest项目的lib文件夹下。
Step3, 建立Service
当然,一个Flex程序,应该是有服务端的。我们通过这个Service层来访问服务端。
首先要对这个Service抽象一下,这也是写在Parsley的BP中的。我们对服务端的业务访问都是由它来代理的。
代码很简单:
package org.cnflex.parsleytest.service
{
public interface ILoginService
{
function login(user:String, passwd:String):void;
}
}
代码不动,接口先行。现在实现这个接口:
package org.cnflex.parsleytest.service
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class LoginServiceImpl extends EventDispatcher implements ILoginService
{
public function LoginServiceImpl(target:IEventDispatcher=null)
{
super(target);
}
public function login(user:String, passwd:String):void
{
//这里要访问服务器。
}
}
}
要注意的是,需要把服务从EventDispatcher继承,这样LoginServiceImpl就可以dispatchEvent了,比如,登录成功,失败,网络异常等事件。
我们先不管login代码里怎么访问服务器。先看看在界面上怎么来调用这个LoginServiceImpl。
这就要使用到Parsley的两个重要功能:Injection,IOC。
这些概念都是从spring framework或者相似的框架中来的。
需要一个配置文件来完成这个,Parsley支持mxml,xml格式,也支持多重配置文件。
现在我们用mxml方式。建立一个mxml配置,为了方便,直接放置于src目录下。
题外:如何建立一个从Object继承的组件。
我们在这个配置中先声明一个RemoteObject,访问服务端全靠它了。
然后再把刚才声明的服务放在这个配置里,把RemoteObject注入到服务中。代码大概为:
<?xml version="1.0" encoding="utf-8"?>
<mx:Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:service="org.cnflex.parsleytest.service.*">
<mx:RemoteObject id="authRO" showBusyCursor="true" endpoint="http://localhost:8000/amf" destination="auth"/>
<service:LoginServiceImpl id="loginService"/>
</mx:Object>
这样,所有在项目里标注Inject标签的变量,都会从这里找。刚才说了,我们希望登录成功,失败等事件从这里发出,那就用Parsley标签来声明一下。
声明事件先:
package org.cnflex.parsleytest.event
{
import flash.events.Event;
public class LoginEvent extends Event
{
public function LoginEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
public static const LOGINSUCCESS:String = "loginSuccess";
public static const LOGINFAIL:String = "loginFail";
}
}
刚才的LoginServiceImpl就变成了:
package org.cnflex.parsleytest.service
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
[ManagedEvents("loginSuccess,loginFail")]
public class LoginServiceImpl extends EventDispatcher implements ILoginService
{
[Inject(id="authRO")]
public var service:RemoteObject;
public function LoginServiceImpl(target:IEventDispatcher=null)
{
super(target);
}
public function login(user:String, passwd:String):void
{
//这里要访问服务器。
}
}
}
我们特意在Inject标签中说明id,就是想找配置文件中的那个相同id的RemoteObject对象。
注意:这个变量是public的,要不然Parsley也访问不到哦~
现在我们有了一切,可以访问服务端了,我们需要用AsyncToken:
public function login(user:String, passwd:String):void{
var token:AsyncToken = service.login(user, passwd);
token.addResponder(new AsyncResponder(onLogin, onFault, token));
}
//如果登录成功了, 就用事件的方式告诉界面,或者其他需要知道的地方。
//一些服务端返回的数据也可以在这里带入
protected function onLogin(event:ResultEvent, token:AsyncToken):void{
var evt:LoginEvent = new LoginEvent(LoginEvent.LOGINSUCCESS);
this.dispatchEvent(evt);
}
//自己实现onFault.
如何知道已经登录成功,失败了呢?我们在主程序上试试:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import org.cnflex.parsleytest.event.LoginEvent;
[MessageHandler(selector="loginSuccess")]
public function onLoginSuc(evt:LoginEvent):void{
//登录后干点啥。。。
}
]]>
</mx:Script>
</mx:Application>
一个MessageHandler就能解决问题,方便吧?
注意:这个方法是public的,要不然Parsley也访问不到哦~
那,我们怎么登录呢?界面上如何调用我们刚才写的一堆的代码?
答案还是Inject。还记得我们在配置中声明了一个LoginServiceImpl吧,把它拿过来:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import org.cnflex.parsleytest.event.LoginEvent;
import org.cnflex.parsleytest.service.ILoginService;
[Inject(id="loginService")]
public var service:ILoginService;
private function onLoginClick():void{
this.service.login('d_yang','******');
}
[MessageHandler(selector="loginSuccess")]
public function onLoginSuc(evt:LoginEvent):void{
//登录后干点啥。。。
}
]]>
</mx:Script>
<mx:Button label="假的登录" click="onLoginClick()"/>
</mx:Application>
好了。大功告成。运行。
但是却不会执行……为啥?
因为缺少了最重要的一步:初始化Parsley:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
preinitialize="FlexContextBuilder.build(Beans)"
addedToStage="dispatchEvent(new Event('configureIOC', true));">
<mx:Script>
<![CDATA[
import org.cnflex.parsleytest.event.LoginEvent;
import org.spicefactory.parsley.flex.FlexContextBuilder;
import org.cnflex.parsleytest.service.ILoginService;
[Inject(id="loginService")]
public var service:ILoginService;
private function onLoginClick():void{
this.service.login('d_yang','******');
}
[MessageHandler(selector="loginSuccess")]
public function onLoginSuc(evt:LoginEvent):void{
//登录后干点啥。。。
}
]]>
</mx:Script>
<mx:Button label="假的登录" click="onLoginClick()"/>
</mx:Application>
注意:这两个事件是不能改的。Parsley要求的很少,这点还是可以原谅的。
本文转自:http://blog.ityao.com/archives/226