| Subcribe via RSS

IOC(DI) in Flex

12月 10th, 2009 | No Comments | Posted in ActionScript3, Flex3, Tips Tricks, ioc

IOC:Inversion of Control(反转控制)

DI:Dependency Injection(依赖注入)

IOC一词来源于Martin Fowler发表的一篇文章,《Inversion of Control Containers and the Dependency Injection pattern》

那是什么被反转控制了?实际上指的是对象之间的依赖关系被反转控制了,原本由类自身维护所需对象实例的创建现在转由外部的IOC容器来维护。这种维护对象实例化的负责方被反转了。而依赖注入(DI)呢?意思更加明确,即获得所依赖对象的方式是由IOC容器从外部直接注入进来,而非我们通常的使用new的方式在类中来完成。

在JAVA中,大家熟知的Spring框架其核心内容便是反转控制及依赖注入。

使用IOC(DI)有什么好处?大致来说有两点:

1、类或模块之间的耦合度降低了,代码更易重用和维护

2、更加便于编写可测试的代码

随着面向对象的Actionscript3.0的推出,尤其是Flex在企业级应用中越来越多的应用,Flex(Flash)应用框架也越来越多,也有不少框架实现了IOC的功能,当然也包括一些独立的IOC容器框架。

image

在as3中实现IOC,核心是使用as3中的反射来完成的,相对来说,as3中的反射比起Java来说确实弱了不少,主要是利用describType返回的属性XML进行解析,而这样对性能会有一定的影响,若在as3中大量使用反射的话,一定要考虑到这一点. 另外,关于使用的配置文件,有以XML来进行的,有以MXML来实现的,也有两都均支持的,需注意的是以XML来实现的好外是我们可以直接更改外部XML而不需要重新编译相应源文件,而若使用MXML的话当你更改配置的话需要重新进行编译.

当然,目前以as3实现的IOC也有很多了,主要两在块:

  • 独立的IOC容器:

Flicc

smartypants-ioc (名字取得不错,呵呵)

SwiftSuspenders (比较小巧)

  • 实现了IOC功能的完整框架:

Spring Actionscript(原名:Prana,此框架现已归入Springsource,几乎是Spring IOC实现的as3翻版,熟悉Spring的Java开发人员几乎不需要什么过渡就能理解)

Swiz(也属于比较成熟的框架了)

Robotlegs(MVCS框架,可集成使用其它任何DI容器,最初建立在smartypants-ioc,目前自身使用SwiftSuspenders)

Parsley(由PowerFlasher开发,个人比较喜欢这个框架,严格意义上来说它不算MVC框架,属于一套Toolkit,你完全可以使用自己的MVC方式来组织)

另外这里一份代码,一个Sample,以不同的IOC框架来实现,应该对大家学习比较有用:

http://code.google.com/p/flex-ioc-examples/

希望大家能找到适合自己项目使用的IOC容器^_^

Flex Custom Component LifeCycle

05月 6th, 2009 | 1 Comment | Posted in ActionScript3, Component, Flex3, LifeCycle, Tips Tricks

谈到Flex学习,大家都知道,其实Flex入门挺容易的,尤其是对其它面向对象语言像Java或C#比较熟悉的开发人员,直接阅读Flex的代码通常也没什么问题,但从另外一方面来说,要想深入学习Flex并灵活运用的话,其实并不那么容易,其中,对组件的生命周期(LifeCycle)的理解则是非常重要的一关,个人感觉的话,若充分理解并掌握了组件的生命周期才算真正Flex入门了:)

 

前段时间,与公司同事分享了一下自己对LifeCycle的经验,当时为了有助于宏观上理解整个Flex应用程序及组件的LifeCycle,自己画了两幅图,分享给大家,希望对大家有用~~~

点击小图可看完整的大图:)

【注】若大家要引用或转载的话,请注明出处,先谢谢了

applifecycle

lifecycle

360Flex及Max2008 sessions

01月 20th, 2009 | No Comments | Posted in 360Flex, ActionScript3, Flex3, MAX2008, RIA, adobe

对于Flex/AIR/BlazeDS/LCDS学习者来说,360Flex及Max2008应该是大家都想参加的会议,但对于大部分人来说,仍是价格不菲,不过还好,最近的360Flex及MAX2008大会的技术演讲大部分均有视频记录,而且效果非常好,相信对大家来说是份不可多得的好资源~~~观看这些视频通常有下面几种方式:

直接通过Adobe.com官方站点访问在线观看:

MAX2008:

通过Adobe Media Player订阅观看,订阅地址如下:

MAX2008:

 

360Flex:

http://sessions.adobe.com/360FlexSJ2008/feed.xml

 

还可以通过以下iTunes地址进行观看:

MAX2008:

http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=299639895

根据字符串内容动态调用相应函数

09月 23rd, 2008 | No Comments | Posted in ActionScript3, Flash, Flex3, Personal

前段时间在做一个程序的时候,遇到需要根据字符串内容调用相应函数的情况,如:从服务器端获取到XML数据文件,需要根据其中command节点的内容来调用相对应的函数,若command节点为”login”,则调用on_login函数,节点内容为”register”,则调用on_register函数…

最开始比较简单,我都是根据字符串内容来switch,这样不太好,经Glen提醒,看是否能根据字符串内容直接去找相应配对的函数执行,函数名统一为字符串内容前加”on_”,经过尝试,采用以下办法来达到需求。

为了程序结构清楚,我建立了一个名为Commandhandler的类,利用getInstance()获取其单例,再定义一commandManager方法,该方法便是根据传入的字符串参数去调用相应的方法,其关键是以[]的方式调用方法,当然在调用之前最好判断是否存在这样的方法。

commandManager函数代码如下:

public function commandManager(func:String):String {
	var functionName:String = "on_" + func;
	var str:String;
	if(this.hasOwnProperty(functionName)) {
		return this[functionName]();
	}
	return null;
}

点击运行示例,在示例上右键点击可查看源码。

Tags: ,

Flash、Flex资源收集之十全大补

07月 23rd, 2008 | No Comments | Posted in ActionScript3, Collection, Flash, Flex3, Lib, RIA, Tool

断断续续收集了Flash、Flex相关的不少资源,但好多存着都没看,加上自己没太整理好,反而到想找的时候找不到。在此做个“十全大补”,来个群英汇萃,一来方便自己,二来大家也可参考参考。这些资源均来自网上,感谢这些作者们。不断更新中……

[毕竟是自己辛苦整理的,转载的话请注明出处:http://www.jexchen.com 谢谢]

APIs、Libs、Components

1、as3ebaylib

http://code.google.com/p/as3ebaylib/

2、as3youtubelib

http://code.google.com/p/as3youtubelib/

3、as3flickrlib

http://code.google.com/p/as3flickrlib/

4、Yahoo ASTRA Flash Components

http://developer.yahoo.com/flash/astra-flash/

5、facebook-as3

http://code.google.com/p/facebook-as3/

6、as3awss3lib

http://code.google.com/p/as3awss3lib/

7、Adobe ActionScript 3:resources:apis:libraries (官方,包括corelib、FlexUnit、Flickr、Mappr、RSS and Atom libraries、Odeo、YouTube)

http://labs.adobe.com/wiki/index.php/ActionScript_3:resources:apis:libraries

8、Tweener   用于过渡与切换的一组动画库

http://code.google.com/p/tweener/

9、uicomponents-as3    一组轻量级的AS3 UI组件库

http://code.google.com/p/uicomponents-as3/

10、as3ds    AS3的数据结构实现

http://code.google.com/p/as3ds/

More »

Tags: , ,

Python与Flex之间Socket通讯

07月 12th, 2008 | No Comments | Posted in ActionScript3, Flex3, Python

在朋友的介绍下,接触了下Python,给人的感觉是,简洁、快速、规范,抽时间多学习学习

尝试了下使用Pyhon创建一简单的服务器,TCP方式,运行服务器,进入监听状态,然后在Flex中使用ActionScript3以Socket方式连接上去,将Flex中用户输入字符串发送到Python服务器,服务器接收到内容后加上时间戳再返回给Flex,显示给用户。

这只是一个非常简单学习的例子( ̄~ ̄;),其中,Python端代码源自《Core Python》一书,Flex端代码源自官方文档,根据需要作了一部分修改,不多说了,将Flex及Python代码贴上来,呵呵~~~

运行效果截图:

2008-07-12_181401

 

服务器端Python代码:

   1: #!/usr/bin/env python
   2: #coding=utf-8
   3: from socket import *
   4: from time import ctime
   5:  
   6: HOST=‘localhost’
   7: PORT=21567
   8: BUFSIZ=4096
   9: ADDR=(HOST, PORT)
  10:  
  11: tcpSerSock = socket(AF_INET, SOCK_STREAM)
  12: tcpSerSock.bind(ADDR)
  13: tcpSerSock.listen(5)
  14:  
  15: while True:
  16:     print ‘waiting for connection…’
  17:     tcpCliSock, addr = tcpSerSock.accept()
  18:     print ‘…connected from:’, addr
  19:  
  20:     while True:
  21:         data = tcpCliSock.recv(BUFSIZ)
  22:         if not data:
  23:             break
  24:         tcpCliSock.send(‘[%s] %s’ % (ctime(), data))
  25:  
  26:  
  27:         tcpCliSock.close()
  28: tcpSerSock.close()

客户端Flex代码:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
   3:     creationComplete="init()">
   4: <mx:Script>
   5:     <![CDATA[
   6:         private var custSocket:Socket;
   7:         [Bindable] private var response:String = "";
   8:  
   9:         private function init():void {
  10:             custSocket = new Socket("localhost", 21567);
  11:             configureListeners();
  12:         }
  13:  
  14:         private function onClick(evt:Event):void {
  15:             sendRequest();
  16:         }
  17:  
  18:         private function configureListeners():void {
  19:             custSocket.addEventListener(Event.CLOSE, closeHandler);
  20:             custSocket.addEventListener(Event.CONNECT, connectHandler);
  21:             custSocket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
  22:             custSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
  23:             custSocket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
  24:         }
  25:  
  26:         private function writeln(str:String):void {
  27:             str += "\n";
  28:             try {
  29:                 custSocket.writeUTFBytes(str);
  30:             }
  31:             catch(e:IOError) {
  32:                 trace(e);
  33:             }
  34:         }
  35:  
  36:         private function sendRequest():void {
  37:             trace("sendRequest");
  38:             writeln(inTxt.text);
  39:             custSocket.flush();
  40:         }
  41:  
  42:         private function readResponse():void {
  43:             var str:String = custSocket.readUTFBytes(custSocket.bytesAvailable);
  44:             response += str;
  45:         }
  46:  
  47:         private function closeHandler(event:Event):void {
  48:             trace("closeHandler: " + event);
  49:             trace(response.toString());
  50:         }
  51:  
  52:         private function connectHandler(event:Event):void {
  53:             trace("connectHandler: " + event);
  54:         }
  55:  
  56:         private function ioErrorHandler(event:IOErrorEvent):void {
  57:             trace("ioErrorHandler: " + event);
  58:         }
  59:  
  60:         private function securityErrorHandler(event:SecurityErrorEvent):void {
  61:             trace("securityErrorHandler: " + event);
  62:         }
  63:  
  64:         private function socketDataHandler(event:ProgressEvent):void {
  65:             trace("socketDataHandler: " + event);
  66:             readResponse();
  67:         }
  68:  
  69:     ]]>
  70: </mx:Script>
  71:     <mx:TextArea text="{response}" id="outTxt"
  72:         height="126" width="283" fontSize="12"/>
  73:     <mx:HBox verticalAlign="bottom" width="282" height="40">
  74:         <mx:TextArea id="inTxt" width="100%" height="100%" fontSize="12"/>
  75:         <mx:Button label="发送"  fontSize="12" click="onClick(event)"/>
  76:     </mx:HBox>
  77:  
  78: </mx:Application>

Tags:

HTTPService读取XML时,当节点为1时的问题解决

07月 12th, 2008 | No Comments | Posted in ActionScript3, Flex3

其实以前就遇到过这个问题,只是这次再次遇到,把最终的解决办法列出来:

问题:

当使用HTTPService读取XML文件时,存在多个XML节点时,其类型为ArrayCollection,但当节点为1时,其类型不是ArrayCollection而是ObjectProxy了

拿一个实际的XML举例,我需要提取其中的Question节点以生成相应投票题目。

情形一:存在多个Question(两个或两个以上)节点时,直接可以将其作为ArrayCollection来使用,没有任何问题;

情形二:当仅存在一个Question节点时,若直接当成ArrayCollection来处理便会出错,通过Debug可以发现,这时的类型为ObjectProxy(关于ObjectProxy类型的含义可以查看参考手册),这时候就需要额外处理了。

 

情形一XML:

<Vote State="ok">
<Survey>
<SurveyHead>
    <Title>aaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Title>
    <Author>1</Author>
</SurveyHead>
<SurveyBody>
<Question>
    <Describe>asdfasdfadf</Describe>
    <Type>单选</Type>
    <Options>
        <item id="1" Content="asdfasdfasdfasd" Result="0"/>
        <item id="2" Content="asdfasdfasdf" Result="0"/>
        <item id="3" Content="dddd" Result="0"/>
    </Options>
   <Hot>0</Hot>
</Question>

<Question>
    <Describe>hstgsdfgsdfg</Describe>
    <Type>多选</Type>
    <Options>
        <item id="1" Content="sdhsdgagf" Result="0"/>
        <item id="2" Content="setesrgsg" Result="0"/>
        <item id="3" Content="35w3asfag" Result="0"/>
    </Options>
   <Hot>0</Hot>
</Question>

</SurveyBody>
</Survey>
</Vote>

情形二XML:

<Vote State="ok">
<Survey>
<SurveyHead>
    <Title>aaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Title>
    <Author>1</Author>
</SurveyHead>
<SurveyBody>
<Question>
    <Describe>asdfasdfadf</Describe>
    <Type>单选</Type>
    <Options>
        <item id="1" Content="asdfasdfasdfasd" Result="0"/>
        <item id="2" Content="asdfasdfasdf" Result="0"/>
        <item id="3" Content="dddd" Result="0"/>
    </Options>
   <Hot>0</Hot>
</Question>
</SurveyBody>
</Survey>
</Vote>

 

最终找到的一个比较好的解决办法如下:

var arry:ArrayCollection;

if(evt.result.Vote.Survey.SurveyBody.Question is ObjectProxy) {

   arry = new ArrayCollection([evt.result.Vote.Survey.SurveyBody.Question]);

}else {
   arry = evt.result.Vote.Survey.SurveyBody.Question as ArrayCollection;
}

 

以后就可以全当成ArrayCollection处理了。

Tags: ,

Flex应用程序启动详解

05月 11th, 2008 | No Comments | Posted in ActionScript3, Flex3, RIA

转载请注明出自:http://www.jexchen.com,谢谢!

编写一个简单的Flex应用程序并不复杂,就算你从来没接触过Flex程序设计,照着帮助的实例步骤,不需花多长时间也能做出一个漂亮简捷的小程序出来。不过,随着对Flex程序编写的深入,会越来越觉得,其实要编写一个好的Flex应用程序并不简单,涉及到各个方面的知识,需要对Flex应用程序的架构、事件机制的处理、设计与程序的结合等等各个方面均要有所掌握。

接下来我会写一个系列文章,对Flex应用程序编写在上述方面所需掌握的知识作一个梳理,希望对大家有所帮助…

这第一部分的内容从Flex应用程序的启动与运行讲起。另外,Flex应用程序总的来说是以事件驱动的程序,因此,大家在深入学习Flex的各个方面知识的时候,应该随时以事件驱动的观点来进行思考。

大家都知道,我们在编写Flex应用程序时,通常是以<mx:Application>标签作为开头,实际上,Flex应用程序在启动运行的时候并不是直接从Application开始运行,在这之前还有一部分悄悄的先运行了,正如大家所看到的,当我们运行编写好的Flex应用程序时,尽管我们没有编写任何与启动进度载入条相关的代码,但无一例外的,应用程序均会为我们自动加上这一部分。因此才有我们看到的如下图所示的标准的Flex loading载入条(在下一篇文章中,我们将一起来改变这千篇一律的载入条,创建自定义的loading效果)。

loading

通常我们所说的Flex应用程序,本质上来说是基于Flex框架、采用ActionScript 3.0编写的Flash应用程序,从这一点来说,它和普通的Flash应用程序没有任何差别。相对来说,传统的使用Flash IDE(如Flash CS3)创建Flash程序时更多的基于“时间线”(Timeline)及“帧”(Frame)的概念,更易于设计师理解;而基于Flex框架来创建的Flash应用程序更多是强调程序性,很少提及“时间线”与“帧”的概念,更易于程序员理解。其实Flex应用程序一样也有时间线,只是这部分由Flex框架隐藏起来了,通常不为大家所熟悉,在默认创建Flex程序时,这一切Flex已帮我们完成了,但了解这部分内容更有助于大家对Flex应用程序的启动有更深刻的认识,以便能对程序更灵活的控制与发挥~~

application

我们来看看上面这幅示意图,Flex应用程序共由两帧组成,第1帧为preloader部分,第2帧为主应用程序部分,此两部分由Flex应用程序的根SystemManager统管,SystemManager是flash.display.MovieClip的子类,影片剪辑(movie clip)支持帧。由于swf属于一种渐进式(progressive)下载的格式,正是由于swf格式这个特性,Flash Player并不需要等待整个程序下载完成便可直接访问已载入帧的内容,因此第一帧通常用来作为应用程序载入时的loading画面显示,一般来说,第一帧包含的内容应该尽可能的少(在第一帧中尽量不要含有Flex框架的组件),以便能很快的下载并立即显示;第二帧才是主应用程序真正的内容,一旦SystemManager实例进入到第二帧后,即开始内部主应用程序运行的生命周期(life cycle),也就是进入我们最为熟悉的<mx:Application>运行的部分(SystemManger实例有一application的属性,在第1帧时,此属性为null,当进入到第2帧时,该属性才指向真正的主程序application实例)

注:帧是时间线的一个基本单元,如PAL电视制式,每秒25帧;而电影通常为每秒24帧,其实和我们这里讲的Flash中的帧类似的概念

记住我们开始所说的,Flex应用程序总的来说是以事件驱动的程序

在程序进入第2帧,主程序application开始运行后,便会相应的触发相应的一系列事件,按事件发生的先后顺序依次来介绍:

preinitialize

应用程序application已实例化,但此时还未创建任何相关的孩子组件(child component)

initialize

此时,创建了相应的孩子组件,但还未对这些子组件进行布局

creationComplete

应用程序application完成全部实例化,并完成所有子组件的布局

apllicationComplete

上面三处事件的完成,表明application内部启动的整个进程完成,接下来便会通知SystemManager派发applicationComplete事件。此时,启动程序启动完成并准备运行。

运行下面这个小程序,再次理解这几次事件,注意:由于在preinitialize事件产生时,此时还未创建任何子组件,故在此事件的处理函数中,不能直接将相应显示的字符串赋给TextArea组件显示。

点击运行程序(右键选择view source可查看源码)

Tags: ,

再谈:Flex程序如何获取html容器传递的URL参数值

04月 24th, 2008 | 1 Comment | Posted in ActionScript3, Flex3

在前面的一篇文章中我们讨论了利用Flex中的ExternalInterface类向swf传递参数。今天我们来谈谈另外一种更简捷的方法!

这次的方法是利用 SWFObject,SWFObject一个开源的JS模块,专门用来在HTML中嵌入Flash(*.swf)文件,利用该模块,使得插入Flash文件更加便捷、安全;并且使用SWFObject能自动检测各主流浏览器对Flash插件的支持并能作相应的处理。

目前SWFObject最新版为2.0,关于SWFObject的一些资源见下面:
官方站点
http://blog.deconcept.com/swfobject/

在google code的地址,这里有SWFObject 2.0的JS包及相关自动代码生成器的下载
http://code.google.com/p/swfobject/

SWFObject 2.0 官方文档(英文)
http://code.google.com/p/swfobject/wiki/SWFObject_2_0_documentation

SWFObject 2.0 官方文档(中文翻译)
http://farthinker.cn/2007/12/27/swfobject-2_0-doc-translation/

SWFObject 的使用非常简单,相信大家看了上面的文档就很清楚了,下面结合实例,谈谈利用SWFObject来获取URL参数值的做法。

我们的做法是,利用SWFObject的HTML容器代码自动产生器产生嵌入模板代码,点此处下载,注意在代码生成器中我们选定Publishing method(发布方式)为 Dynamic publishing(动态发布),编码设定为utf-8,关于静态发布与动态发布的详细介绍见官方文档。SWFObject 2.0 为开发人员提供了一些非常有用的函数,例如,我们要想获取*.html?name=JexChan&address=ChengDu这样的参数,就可以使用swfobject的getQueryParamValue函数,此函数可以直接获取以前面形式出现的get方式提交的参数值对,获取到参数值后赋给flashvars变量,最后再作为embedSWF方法的参数传递给相应的SWF文件。

More »

Tags: , ,

Flex程序如何获取html容器传递的URL参数值

04月 12th, 2008 | 2 Comments | Posted in ActionScript3, Flex3

Jex 原创,转载请注明出自:http://www.jexchen.com,谢谢!

我们经常在Flex程序需要用从外部html向swf文件传递参数,(类似 test.html?name=jex&address=chengdu 地址中问号后面的参数对值)

首先要明确的是,一般我们在使用Flex Builder进行Flex开发时,编译后自动以html容器将swf文件包装起来了,所以一般来说,我们直接运行的是html,而非直接运行生成的swf文件。而Flex应用程序要获取外部html容器传入的参数,通常是用JavaScript来获取到相应参数,再让javaScript传递给ActionScript。

在Flex应用程序中,我们通常要用到ExternalInterface类,ExternalInterface主要用来让ActionScript直接与Flash Player容器进行通信。ExernalInterface类通常作为ActionScript与JavaScript进行通信的桥梁。

为了获取从html传入的URL参数,通常传递的顺序是:html容器—>JavaScript—>ExternalInterface—>ActionScript

具体实现:
在Flex中,通过调用ExternalInterface的call方法,参数为要调用的JavaScript函数,并返回JS函数调用的结果。如:

ExternalInterface.call("JavaScript函数");

在JS中,Window对象用来代表一个Web浏览器窗口,而窗口的Location对象则代表了当前显示的URL,于是,要想获取URL中的参数,

通常使用下面的语句:

window.location.href.toString  //得到URL的完整文本
 
window.location.search.substring  //得到问号后面部分的URL文本

:这里window属性引用的Window对象自身,而Window对象的location属性引用的是Location对象。

More »

Tags: ,