使用Parsley构建Flex Application (翻译)

原文链接 http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/

在最近研究了Swiz和SprintActionScript(1,2,3)之后,我决定再试用一下Parsley framework,创建Parsley版本的inSync,这是一个简单的管理联系人的应用,我经常用这个作为demo演示Flex和Adobe AIR的特性和技巧

parsley.png

Parsley首先是一个依赖注入的framework。它还提供了一种有趣的消息机制作为基础。依赖注入就不多说了,之前Swiz和Spring ActionScript的文章中有一些背景资料和很多细节作为参考。

如果只想运行程序或者看看源代码,链接在这:程序源代码

配置 Object

Parsley让你有多种方式配置核心的objects(其他的组件依赖于这些对象),使用MXML(像Swiz),使用XML(像Spring ActionScript)或者ActionScript。或者各种方式的组合。甚至可以扩展framework,创造你自己的配置机制

就inSyc而言,我选择了MXML的方式(Config.mxml),如下

 
<?xml version="1.0" encoding="utf-8"?>
<Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:services="insync.parsley.services.*">
 
    <mx:RemoteObject
            id="contactRO"
            destination="contacts"
            endpoint="http://localhost:8400/samples/messagebroker/amf"
            showBusyCursor="true" />
 
    <services:ContactService />
 
</Object>

注,在实际项目中,你并不应该hardcode service的endpoint。使用XML在外部(更外了)来配置endpoint。这里有更多相关的讨论

初始化Framework

你选择了那种类型的配置方式,就通过与之对应的ContextBuilder来初始化framework。下面是inSync的Main文件。我让Parsley在preinitialize event中初始化。

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:views="insync.parsley.views.*"
        paddingTop="0" paddingLeft="0" paddingRight="0" paddingBottom="0"
        preinitialize="FlexContextBuilder.build(Config)">
 
        <mx:Script>
                <![CDATA[
                        import org.spicefactory.parsley.flex.FlexContextBuilder;
                ]]>
        </mx:Script>
 
        <mx:Style source="styles.css" />
 
        <views:MainView />
 
</mx:Application>

依赖注入

Parsley支持构造函数注入,方法注入和属性注入(指定type和指定id)

下面的例子(ContactForm.mxml),framwork将注入IContactService的具体实现,实例是由Config.mxml创建的ContactService,通过指定type注入。针对接口编程,让view对IContactService的具体实现解耦。

注:Parsley并不强制你使用特定的设计模式。就这个简单的sample而言,我直接把Service注入到view。使用接口一定程度的做到了解耦,你当然还可以使用其他的模式(比如Presentation Model)来架构更高层的抽象。Parsley的依赖注入和消息机制让应用这些模式更加容易。

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
        addedToStage="dispatchEvent(new Event('configureIOC', true))">
 
        <mx:Script>
                <![CDATA[
 
                import insync.parsley.model.Contact;
                import insync.parsley.services.IContactService;
 
                [Inject]
                public var service:IContactService;
 
                [Bindable]
                public var contact:Contact;
 
                private function save():void
                {
                        contact.firstName = firstName.text;
                        contact.lastName = lastName.text;
                        contact.email = email.text;
                        service.save(contact);
                }
 
                private function remove():void
                {
                        service.remove(contact);
                }
 
                ]]>
        </mx:Script>
 
        <mx:Form>
                <mx:FormItem label="Id">
                        <mx:TextInput text="{contact.id}" enabled="false"/>
                </mx:FormItem>
                <mx:FormItem label="First Name">
                        <mx:TextInput id="firstName" text="{contact.firstName}"/>
                </mx:FormItem>
                <mx:FormItem label="Last Name">
                        <mx:TextInput id="lastName" text="{contact.lastName}"/>
                </mx:FormItem>
                <mx:FormItem label="Email">
                        <mx:TextInput id="email" text="{contact.email}"/>
                </mx:FormItem>
        </mx:Form>
 
        <mx:HBox left="12" bottom="12">
                <mx:Button label="Save" click="save()"/>
                <mx:Button label="Delete" click="remove()"/>
        </mx:HBox>
 
</mx:Canvas>

注意到,view为了得到注入进来依赖对象,在被添加到stage的时候,view必须dispatch "configureIOC"事件

消息

Parsley提供通用的消息机制,允许在对象之间松耦合,灵活和易用的传递消息:

event的dispatcher和handler不知道彼此
event的dispatcher和handler和framework之间也是松耦合的,通过Flex的方式dispatch事件

我们来看一下inSync中Search这一块儿。

ToolBar中有一个TextInput让用户输入查找条件
ContactList在DataGrid中显示查到的结果

Toolbar如下(去掉了逻辑不相关的代码以清晰)

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"
        addedToStage="dispatchEvent(new Event('configureIOC', true))">
 
        <mx:Metadata>
                [ManagedEvents("search")]
        </mx:Metadata>
 
        <mx:Script>
                <![CDATA[
                        import insync.parsley.events.SearchEvent;
                ]]>
        </mx:Script>
 
        <mx:Label text="Search:" top="18" right="164"/>
 
        <mx:TextInput id="searchBox" right="0" top="16"
                change="dispatchEvent(new SearchEvent(SearchEvent.SEARCH, searchBox.text))"/>
 
</mx:Canvas>

注意看input的内容change的时候dispatch SearchEvent事件。

使用ManagedEvents MetaData定义这些个event是被framework管理的,意思说framework将保证到时候这些事件会被对其感兴趣的部分正确的收到。

怎么注册被framework管理的event的listener呢?我们在给function加注[MessageHandler]Metadata,这个函数就自动变成了对应事件的handler,不管显示列表结构,或者事件冒泡与否。

ContactList如下(去掉了不相关的代码)

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
        addedToStage="dispatchEvent(new Event('configureIOC', true))">
 
        <mx:Script>
                <![CDATA[
 
                        import mx.controls.Alert;
                        import mx.collections.ArrayCollection;
                        import mx.rpc.events.FaultEvent;
                        import mx.rpc.AsyncToken;
                        import mx.rpc.AsyncResponder;
                        import mx.rpc.events.ResultEvent;
 
                        import insync.parsley.events.SearchEvent;
                        import insync.parsley.services.IContactService;                 
 
                        [Inject]
                        [Bindable]
                        public var service:IContactService;
 
                        [Bindable]
                        public var contacts:ArrayCollection;
 
                        [MessageHandler]
                        public function searchHanlder(event:SearchEvent):void
                        {
                                service.getContactsByName(searchStr).addResponder(new AsyncResponder(getContacts_result, faultHandler));
                        }
 
                        private function getContacts_result(event:ResultEvent, token:AsyncToken):void
                        {
                                contacts = event.result as ArrayCollection;
                        }       
 
                        private function faultHandler(event:FaultEvent):void
                        {
                                Alert.show(event.fault.faultString);
                        }               
 
                ]]>
        </mx:Script>
 
        <mx:DataGrid id="dg" dataProvider="{contacts}" width="100%" top="0" left="0" right="0" bottom="0"/>
 
</mx:Canvas>

单单使用[MessageHandler] ,在Application范围,每次和handler参数相同类型的事件被dispatch的时候,handler都会被调用。为了更好的控制handler该被调用,可以指定selector为某些特定的event type。比如MainView.mxml,contactDeleted函数被注册为只监听ContactEvent.DELETED事件的handler,如下:

 
[MessageHandler(selector="contactDeleted")]
public function contactDeletedHandler(event:ContactEvent):void
{
}

Parsley还有更多的消息使用方法。比如可以用[MessageBinding]来bind一个对象的属性到一个事件的属性:

 
[MessageBinding(messageProperty="result",type=" mx.rpc.events.ResultEvent")]
public var contacts:ArrayCollection;

实例代码的安装调试

1,下载整个Project
2,导入到Flash Builder
3,运行application。这个application默认使用MockService(ContactServiceMock),所以不需要后台

如果需要远端service而不是MockService

1,替换<services:ContactServiceMock/>为<services:ContactServiceRemote/>
2,安装BlazeDS turnkey server
3,下载insync-parsley-java.zip 后解压到本地
4,复制classes/insync 到blazeds/tomcat/webapps/samples/WEB-INF/classes/insync
5,添加destination到blazeds/tomcat/webapps/samples/WEB-INF/flex/remoting-config.xml

 
<destination id="contacts">
        <properties>
            <source>insync.dao.ContactDAO</source>
            <scope>application</scope>
        </properties>
</destination>

6,复制insync/sampledb/insync 到blazeds/sampledb/insync
7,编辑blazeds/sampledb下的server.properties 按照下面的方式把inSync的database添加到启动项中
8,启动database (用startdb)
9,启动blazeDS
10,运行Application

转载于:https://www.cnblogs.com/flashproto/archive/2010/05/22/1741358.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值