当前位置: 首页 > 工具软件 > PyAMF > 使用案例 >

Flex + Python + PyAMF编程实例

阎博易
2023-12-01

Flex + Python + PyAMF编程实例

Cairgorm + Django + PyAMF简易教程

一、技术简介

1. Cairngorm框架

    Cairngorm是一个轻量级的用于Flex项目开发的MVC框架,主要由vo、command、event、controller、service、delegate和modellocator等部分构成。其中vo用于数据对象的封装;service主要用于与远程服务器端打交道;delegate为业务逻辑层,接收command对象传来的请求并通过调用service中的方法来处理请求;event为自定义事件;command会接受并处理相应的event;controller通过调用addCommand方法将event和相应的command联系起来; modellocator存储公共变量;view为应用界面。

2. Django框架

    django是一个基于python的web开发框架。开发者通常需要编辑的文件有:view,用于实现业务逻辑和动态页面显示;models,数据表对象;forms,表格对象;url,联系访问地址和处理模块;setting,设置django服务器。


二、开发环境

1. 客户端:Win7,FlexBuilder3,Cairngorm

2. 服务器端:CentOS,Python2.5,django.VERSION(1, 2, 4, 'final', 0)


三、开发过程

1. flex项目开发

1)新建flex project如命名为CairngormDemo-->选中libs并右键导入cairngorm.swc文件

2)新建folder “vo”,在vo中新建ActionScript Class “ ContactVO”,内容如下:

package vo

{

    //对象属性必须与服务器端model中相应的类对应

    //[RemoteClass (alias="vo.ContactVO")]跟服务器端的Contact绑定

    //Bindable标签为Flex中的元标签,其作用为绑定,即当被绑定者改变的时候(被赋值了),可能通知其它被其影响(赋值给它们)的变量发生改变,这里的“可能”就需要编译器来判断。

    [Bindable]

    public class ContactVO extends Object

    {

        public var id:int;

        public var name:String;

        public var address:String;

        public function ContactVO(name:String,address:String)

        {

            this.name = name;

            this.address = address;

        }

    }

}

3)新建folder “model”,在model中新建ActionScript Class “MyModelLocator”并实现com.adobe.cairngorm.model.ModelLocator接口,内容如下:

package model

{

    //model类使用了单例模式,主要用于存放公共变量

    import com.adobe.cairngorm.model.ModelLocator;

    import mx.collections.ArrayCollection;

    import vo.ContactVO;


    public class MyModelLocator implements ModelLocator

    {

        //ArrayElementType元数据标签可以让定义的数组元素的数据类型

        [ArrayElementType("ContactVO")]

        private static var myModelLocator:MyModelLocator=null;

        [Bindable]

        public var contactColl : ArrayCollection = new ArrayCollection();

        public function MyModelLocator()

        {

        }


        public static function getInstance():MyModelLocator

        {

                if(myModelLocator == null)

                    myModelLocator = new MyModelLocator();

                return myModelLocator;

        }

    }

}

4)新建folder “service”,在vo中新建ActionScript Class “ MyService”,内容如下:

package service

{

    //service类使用单例模式,用于与后台django通信

    import mx.messaging.ChannelSet;

    import mx.messaging.channels.AMFChannel;

    import mx.rpc.AsyncToken;

    import mx.rpc.remoting.RemoteObject;

    import vo.ContactVO;

    public class MyService

    {

        //AMFChannel uri

        public var serverAmfPath:String;

        static private var instance:MyService = null;

        private var ro:RemoteObject;

        public function MyService()

        {

            initAMFChannel();

        }

        static public function getInstance():MyService

        {

            if(instance == null)

                instance = new MyService();

            return instance;

        }


        //初始化amf信道

        private function initAMFChannel():void

        {

            var cs:ChannelSet = new ChannelSet(null,false);

            //serverAmfPath用于定义服务器地址

            serverAmfPath = "http://192.168.6.140:8000/gateway/";

            var amfc:AMFChannel = new AMFChannel("amfChannel",serverAmfPath);

            cs.addChannel(amfc);

            //destination属性是网关服务的名称,在本例中为myservice

            ro = new RemoteObject("myservice");

            ro.channelSet = cs;

        }

        //通过RemoteObject调用服务器端方法

        public function saveContact(contact:ContactVO):AsyncToken

        {

            var token:AsyncToken = ro.saveContact(contact.name,contact.address);

            return token;

        }

        public function getContactList():AsyncToken

        {

            var token:AsyncToken = ro.getContactList();

            return token;

        }

    }

}

5)新建folder “business”,在vo中新建ActionScript Class “ MyDelegate”,内容如下:

package business

{

    //调用service类与服务器通信

    import mx.rpc.IResponder;

    import mx.rpc.AsyncToken;

    import service.MyService;

    import vo.ContactVO;

    import mx.controls.Alert;

    public class MyDelegate

    {

        private var responder:IResponder;

        private var serv:MyService;

        public function MyDelegate(responder:IResponder)

        {

            this.responder = responder;

            this.serv = MyService.getInstance();

        }

        //调用代理方法

        public function addContact(contact:ContactVO):void

        {

            var token:AsyncToken = this.serv.saveContact(contact);

            token.addResponder(this.responder);

        }

        public function getContactList():void

        {

            var token:AsyncToken = this.serv.getContactList();

            token.addResponder(this.responder);

        }

    }

}

6)新建folder “event”,在event中新建ActionScript Class “AddContactEvent”和“GetContactListEvent”,均继承com.adobe.cairngorm.control.CairngormEvent类,内容分别如下:

package event

{

    //自定义事件,添加通信记录

    import com.adobe.cairngorm.control.CairngormEvent;

    import vo.ContactVO;


    public class AddContactEvent extends CairngormEvent

    {

        public static const ADD_CONTACT_EVENT:String = "addcontact";

        public var contactVO:ContactVO;

        public function AddContactEvent(contactVO:ContactVO)

        {

            super(AddContactEvent.ADD_CONTACT_EVENT);

            this.contactVO = contactVO;

        }

    }

}

------------------------------------------------------------------------------------------------------------

package event

{

    import com.adobe.cairngorm.control.CairngormEvent;

    import vo.ContactVO;


    public class GetContactListEvent extends CairngormEvent

    {

        public static const GET_CONTACT_LIST_EVENT:String = "getcontactlist";

        public function GetContactListEvent()

        {

            super(GetContactListEvent.GET_CONTACT_LIST_EVENT);

        }

    }

}

7)新建folder “command”,在command中新建ActionScript Class “AddContactCommand”和“GetContactListCommand”,均实现com.adobe.cairngorm.commands.ICommand接口,内容分别为:

package command

{

    //接收事件后,交给相应的command处理

    import business.MyDelegate;

    import com.adobe.cairngorm.commands.ICommand;

    import com.adobe.cairngorm.control.CairngormEvent;

    import event.AddContactEvent;

    import model.MyModelLocator;

    import mx.controls.Alert;

    import mx.rpc.Responder;

    import mx.rpc.events.ResultEvent;

    import vo.ContactVO;


    public class AddContactCommand implements ICommand

    {

        public var ml:MyModelLocator = MyModelLocator.getInstance();

        public function AddContactCommand()

        {

        }


        public function execute(event:CairngormEvent):void

        {

            //接收传递来的数据,并存于addContactEvent变量

            var addContactEvent:AddContactEvent = AddContactEvent(event);

            var responder:Responder = new Responder(result,fault);

            var delegate:MyDelegate = new MyDelegate(responder);

            delegate.addContact(addContactEvent.contactVO);

        }

        //命令运行正常的处理函数

        public function result(evt:ResultEvent):void

        {

            ml.contactColl.addItem(evt.result);

        }

        public function fault(evt:ResultEvent):void

        {

            Alert.show(evt.toString());

        }

    }

}

------------------------------------------------------------------------------------------------------------

package command

{

    import business.MyDelegate;

    import com.adobe.cairngorm.commands.ICommand;

    import com.adobe.cairngorm.control.CairngormEvent;

    import model.MyModelLocator;

    import mx.collections.ArrayCollection;

    import mx.rpc.Responder;

    import mx.rpc.events.ResultEvent;


    public class GetContactListCommand implements ICommand

    {

        public var ml:MyModelLocator = MyModelLocator.getInstance();

        public function GetContactListCommand()

        {

        }


        public function execute(event:CairngormEvent):void

        {

            var responder:Responder = new Responder(result,fault);

            var delegate:MyDelegate = new MyDelegate(responder);

            delegate.getContactList();

        }

        public function result(evt:ResultEvent):void

        {

            ml.contactColl = new ArrayCollection(evt.result as Array)

        }

        public function fault(evt:ResultEvent):void

        {

        }

    }

}

8)新建folder “model”,在model中新建ActionScript Class “Controller”,继承com.adobe.cairngorm.control.FrontController,内容如下:

package control

{

    //接收自定义事件,并绑定到处理该事件的Command类

    import com.adobe.cairngorm.control.FrontController;

    import command.AddContactCommand;

    import event.AddContactEvent;

    import event.GetContactListEvent;

    import command.GetContactListCommand;

    public class Controller extends FrontController

    {

        public function Controller()

        {

            this.addCommand(AddContactEvent.ADD_CONTACT_EVENT,AddContactCommand);

            this.addCommand(GetContactListEvent.GET_CONTACT_LIST_EVENT,GetContactListCommand);

        }

    }

}

9)新建folder “view”,在view中新建MXML Component “view”,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="564" height="220">

<mx:Script>

 <![CDATA[

   import mx.collections.ArrayCollection;

   import vo.ContactVO;

   import event.AddContactEvent;

   import com.adobe.cairngorm.control.CairngormEventDispatcher;

  

   [Bindable]

   public var contactColl:ArrayCollection = new ArrayCollection();

        

   private function addContact():void

   {

    var contactVO : ContactVO = new ContactVO(xxName.text,xxAddr.text);

    var event : AddContactEvent = new AddContactEvent( contactVO );

     CairngormEventDispatcher.getInstance().dispatchEvent( event );

     

     xxName.text="";

     xxAddr.text="";

  }

 ]]>

</mx:Script>

<mx:Form id="addcontactForm">     

         <mx:FormItem label="姓名: ">

             <mx:TextInput id="xxName"/>

         </mx:FormItem>    

         <mx:FormItem label="地址: ">

             <mx:TextInput id="xxAddr"/>

         </mx:FormItem>          

         <mx:Button label="添加" click="addContact()"/>

     </mx:Form> 

  <mx:VRule  height="100%" strokeColor="#DDDDDD"/>

  <mx:DataGrid dataProvider="{contactColl}" width="308" height="220" alternatingItemColors="[#86EFF0, #FFFFFF]">

  <mx:columns>

  <mx:DataGridColumn headerText="姓名" dataField="name" width="100"/>

  <mx:DataGridColumn headerText="地址" dataField="address"/>

  </mx:columns>

  </mx:DataGrid>

</mx:HBox>

10)编写主模块

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"

xmlns:v="view.*" xmlns:c="control.*" creationComplete="init()">

<mx:Script>

<![CDATA[

    import model.MyModelLocator;

    import com.adobe.cairngorm.control.CairngormEventDispatcher;

    import event.GetContactListEvent;

    [Bindable]

    public var ml:MyModelLocator = MyModelLocator.getInstance();

    public function init():void

    {

        var event:GetContactListEvent = new GetContactListEvent();

        CairngormEventDispatcher.getInstance().dispatchEvent(event);

    }

]]>

</mx:Script>

<c:Controller id="addControl"/>

<v:view id="addView" contactColl="{ml.contactColl}"/>

</mx:Application>


3.Django项目开发

0)准备工作:配置mysql数据库使其支持中文存取;安装PyAMF模块

1)创建django项目和应用

# mkdir /tmp/test

# cd /tmp/test

# django-admin.py startproject contact

# cd contact

# python manage.py startapp addcontact

2)编辑数据模型文件

# cd addcontact

# vi models.py

//内容如下

from django.db import models

class Contact(models.Model):

        name = models.CharField(max_length=30)

        address = models.CharField(max_length=100)

        def __unicode__(self):

                return self.name

3)编辑setting.py文件,主要内容如下:

。。。

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.

        'NAME': 'contact',                      # Or path to database file if using sqlite3.

        'USER': 'root',                      # Not used with sqlite3.

        'PASSWORD': 'password',   

。。。

INSTALLED_APPS = (

    。。。

    # Uncomment the next line to enable the admin:

    'django.contrib.admin',

    'contact.addcontact',

)

。。。

4)编辑url.py文件,内容如下

from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:

from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',

 。。。

    # Uncomment the next line to enable the admin:

    (r'^admin/', include(admin.site.urls)),

)

5)同步数据库

# python manage.py syncdb

。。。

6)在contact目录下创建amfgateway.py文件,内容如下:

import pyamf

from pyamf.flex import ArrayCollection, ObjectProxy

from pyamf.remoting.gateway.django import DjangoGateway

from contact.addcontact.models import Contact


#pyamf.register_class(Contact, 'vo.ContactVO')


def saveContact(request, name, address):

   c = Contact()

   c.name = name

   c.address = address

   c.save()

   return c


def getContactList(request):

   emailList = Contact.objects.all()

   return emailList


services = {

   'myservice.getContactList':getContactList,

   'myservice.saveContact':saveContact,

}


myGateway = DjangoGateway(services, expose_request=True)

7)在url.py中添加语句(r'^gateway/', 'contact.amfgateway.myGateway'),,其末尾的“,”一定不要忘记

8)编写c.py测试文件如下:

from pyamf.remoting.client import RemotingService

import sys

gateway = RemotingService('http://127.0.0.1:8000/gateway/')

saveContact = gateway.getService('myservice.saveContact')

rs = saveContact('testName','testAddress')

print rs

sys.exit(0)

9)启动服务器

//我的虚拟机的ip为192.168.6.140

# python manage.py runserver 192.168.6.140:8000

10)运行测试程序,测试amf是否工作正常


4.启动客户端Flex项目







你可能也喜欢

 类似资料: