天天看点

Parsley框架之Hello World

作者:Daniel Yang 
(替阿银开个头。写一个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要求的很少,这点还是可以原谅的。      

继续阅读