使用FLEX进行多文件上传和自定义上传信息

在Web应用中上传文件是比较常见的需求,在这里通过一个实际应用向大家介绍一下在Flex下如何进行多文件上传,并在上传文件的同时提供一些自定义描述信息以便数据逻辑处理。

功能需求  

首先通过以下界面了解一下需求:

 

主要功能包括:

  1)允许添加多个上传的文件

  2)自定义文件标题

  3)可以对没上传的或正在上传的文件删除

  4)上传过程把窗体隐藏在后台,不影响用户的其他的操作(这个就很简单,把窗体隐藏起来在主界面显示个上进工作按钮就可以了,需要的时候再点击一下查看进度)

 

定义文件上下传类

ContractedBlock.gifExpandedBlockStart.gifCode
package Codes
{
    import HFSoftFx.HFSoftCoreFun;
    
    import flash.events.DataEvent;
    import flash.events.ProgressEvent;
    import flash.net.FileReference;
    import flash.net.URLRequest;
    
    
public dynamic class UploadFile
    {
        
public static var DEFAULT:int=0;
        
public static var LOADING:int=1;
        
public static var COMPLETE:int=2;
        
public function UploadFile()
        {
        }
        
private var mState:int = DEFAULT;
        
public function get State():int
        {
            
return mState;
        }
        
private var mName:String;
        
public function get Name():String
        {
            
return mName;
        }
        
public function  set Name(value:String):void
        {
            mName
=value;
        }
        
        
private var mSize:int;
        
public function get Size():int
        {
            
return mSize;
        }
        
public function set Size(value:int):void
        {
            mSize 
= value;
        }
        
private var mLoadSize:int;
        
public function get LoadSize():int
        {
            
return mLoadSize;
        }
        
public function set LoadSize(value:int):void{
            mLoadSize 
=value;
        }
        
        
private var mFileRef:FileReference;
        
public function get FileRef():FileReference
        {
            
return mFileRef;
        }
        
public function set FileRef(value:FileReference):void
        {
            mFileRef
=value;
        }
        
public function Upload(request:URLRequest,complete:Function=null,
        progress:Function
=null):void{
            FileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,
            function(
event:DataEvent){
                var str:String 
=  event.data.substr(1,event.data.length-1);
                var x:XML
=new XML(str);
                
if(x.Exception !='' && x.Exception !=null )
                {
                    HFSoftCoreFun.AlertError(x.Exception);
                }
                
else
                {
                    mState 
= COMPLETE;
                    
if(complete!=null)
                        complete();
                }
                    
            });
            FileRef.addEventListener(ProgressEvent.PROGRESS
                ,function(
event:ProgressEvent){
                    LoadSize
=event.bytesLoaded;
                    Size 
=event.bytesTotal;
                    
if(progress!=null)
                        progress();
                    
                });
            mState
= LOADING;
            FileRef.upload(request);
            
        }
    }
}

类并不复杂只是定义了一些简单的成员,为什么要把类定义成动态呢,主要是为了方便扩展一些属性成员。

这个类的主要方法就是

 

ContractedBlock.gifExpandedBlockStart.gifCode
        public function Upload(request:URLRequest,complete:Function=null,
        progress:Function
=null):void{
            FileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,
            function(
event:DataEvent){
                var str:String 
=  event.data.substr(1,event.data.length-1);
                var x:XML
=new XML(str);
                
if(x.Exception !='' && x.Exception !=null )
                {
                    HFSoftCoreFun.AlertError(x.Exception);
                }
                
else
                {
                    mState 
= COMPLETE;
                    
if(complete!=null)
                        complete();
                }
                    
            });
            FileRef.addEventListener(ProgressEvent.PROGRESS
                ,function(
event:ProgressEvent){
                    LoadSize
=event.bytesLoaded;
                    Size 
=event.bytesTotal;
                    
if(progress!=null)
                        progress();
                    
                });
            mState
= LOADING;
            FileRef.upload(request);
            
        }

 

参数request是定义接收文件的URLRequest

参数complete和progress分别是上传成功和上传进度回调方法。

 窗体代码

ContractedBlock.gifExpandedBlockStart.gifCode
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="628" height="300" title="上传文件" showCloseButton="true" xmlns:net="flash.net.*">
    
<mx:close>
        
<![CDATA[
        OnWorkingChange();
            PopUpManager.removePopUp(
this);
            
        ]]
>
    
</mx:close>
    
<mx:Canvas width="100%" height="100%">
    
<mx:VBox left="10" right="20" verticalAlign="middle" horizontalAlign="center">
    
<mx:Repeater    dataProvider="{mUploadFiles}" id="rp" width="100%" height="100%">
        
<mx:HBox data="{rp.currentItem}"  verticalAlign="middle" height="26" horizontalAlign="center">
        
<mx:render>
            
<![CDATA[
                var hb:HBox
=HBox(event.target);
                var pb:ProgressBar
= ProgressBar(hb.getChildByName("pb1"));
                var uf:UploadFile
=UploadFile(hb.data);
                pb.setProgress(uf.LoadSize,uf.Size);    
            ]]
>
        
</mx:render>
        
<mx:Button   visible="{rp.currentItem.State!=UploadFile.COMPLETE}" data="{rp.currentIndex}" icon="@Embed(source='http://www.cnblogs.com/Imanges/delete16.png')" width="28">
                
<mx:click>
                    
<![CDATA[
                        DeleteUploadItem(
int(event.target.data));
                    ]]
>
                
</mx:click>
            
</mx:Button>
            
<mx:Label  width="180" text="{rp.currentItem.Name}"/>
            
<mx:TextInput data="{rp.currentItem}" text="{rp.currentItem.Title}" width="206">
                
<mx:change>
                    
<![CDATA[
                        
event.target.data.Title = event.target.text;
                    ]]
>
                
</mx:change>
            
</mx:TextInput>
            
<mx:ProgressBar  id="pb1"   labelPlacement="center"   mode="manual"   width="106" fontWeight="normal"/>
        
</mx:HBox>
        
<mx:HRule width="100%"/>
    
</mx:Repeater>
    
</mx:VBox>
    
</mx:Canvas>
    
<mx:ControlBar horizontalAlign="right" verticalAlign="middle">
        
<mx:Button label="上传">
            
<mx:click>
                
<![CDATA[
                    Upload_File();
                ]]
>
            
</mx:click>
        
</mx:Button>
        
<mx:Button label="确定">
            
<mx:click>
                
<![CDATA[
                OnWorkingChange();
                    PopUpManager.removePopUp(
this);
                ]]
>
            
</mx:click>
        
</mx:Button>
    
</mx:ControlBar>
    
<mx:initialize>
        
<![CDATA[
            My
=this;
        ]]
>
    
</mx:initialize>
        
<mx:Script>
        
<![CDATA[
            import Codes.PopUpEffect;
            import mx.core.IFlexDisplayObject;
            import mx.managers.PopUpManager;
            import mx.controls.ProgressBar;
            import Codes.UploadFile;
            import Codes.SysConfig;
            import flash.net.URLRequest;
            import Codes.Untity;
            import flash.net.URLVariables;
            import flash.net.FileReference;
            import HFSoftFx.HFSoftCoreFun;
            
            
private var My:IFlexDisplayObject;
            [Bindable]
            
private var mUploadFiles:Array=new Array();
            
private var intervalId:uint;
            
public var WorkingChange:Function;
            
private function OnWorkingChange():void{
                
if(WorkingChange!=null)
                    WorkingChange();
            }
            
public function get UploadFiles():Array
            {
                
return mUploadFiles;
            }
            
private function DeleteUploadItem(index:int)
            {
                var item:UploadFile  
= UploadFile(mUploadFiles[index]);
                item.FileRef.cancel();
                mUploadFiles.splice(index,
1);
                OnWorkingChange();
                rp.executeBindings(
true);
                
if(mUploadFiles.length==0)
                    PopUpEffect.Hide(My);
                    
            }
            
public function Upload_File():void{
                
                var item:UploadFile  
= UploadFile(mUploadFiles[0]);
                var request:URLRequest 
= Untity.GetUploadFileRequest();
                var variables:URLVariables
=new  URLVariables();
                variables.Title 
= item.Title;
                variables.FolderID 
= item.FolderID;
                request.data
=variables;
                item.Upload(request,function(){
                    
                    DeleteUploadItem(
0);
                    
if(mUploadFiles.length>0)
                    intervalId
=flash.utils.setInterval(function(){
                            flash.utils.clearInterval(intervalId);
                            
                            Upload_File();
                        },
500,null);
                },function(){
                    rp.executeBindings(
true);
                });
            }
            
public function AddItem(files:FileReferenceList,folderid:int):void{
                var item:UploadFile;
                var  fr:FileReference;
                
for (var i:uint = 0; i < files.fileList.length; i++) {
                    fr 
= FileReference(files.fileList[i]);
                       
if(fr.size>SysConfig.ImageMaxSize)
                       {
                           HFSoftCoreFun.AlertError(fr.name
+"文件大于"+(SysConfig.ResourceFileMaxSize/1024)+"(KB)");
                           
break;
                       }
                       item 
=new UploadFile();
                    item.FileRef 
= fr;
                    item.FolderID
=folderid;
                    item.Title 
= fr.name;
                    item.Name
= fr.name;
                    item.Size 
= fr.size;
                    mUploadFiles.push(item);
                   
                }
                rp.executeBindings(
true);
            }

        ]]
>
    
</mx:Script>
    
</mx:TitleWindow>

窗体有两个主要方法:

通过FileReferenceList把选择的文件添加到窗体列中

ContractedBlock.gifExpandedBlockStart.gifCode
            public function AddItem(files:FileReferenceList,folderid:int):void{
                var item:UploadFile;
                var  fr:FileReference;
                
for (var i:uint = 0; i < files.fileList.length; i++) {
                    fr 
= FileReference(files.fileList[i]);
                       
if(fr.size>SysConfig.ImageMaxSize)
                       {
                           HFSoftCoreFun.AlertError(fr.name
+"文件大于"+(SysConfig.ResourceFileMaxSize/1024)+"(KB)");
                           
break;
                       }
                       item 
=new UploadFile();
                    item.FileRef 
= fr;
                    item.FolderID
=folderid;
                    item.Title 
= fr.name;
                    item.Name
= fr.name;
                    item.Size 
= fr.size;
                    mUploadFiles.push(item);
                   
                }
                rp.executeBindings(
true);
            }

对列表文件进行上传,更新窗体内容。

ContractedBlock.gifExpandedBlockStart.gifCode
            public function Upload_File():void{
                
                var item:UploadFile  
= UploadFile(mUploadFiles[0]);
                var request:URLRequest 
= Untity.GetUploadFileRequest();
                var variables:URLVariables
=new  URLVariables();
                variables.Title 
= item.Title;
                variables.FolderID 
= item.FolderID;
                request.data
=variables;
                item.Upload(request,function(){
                    
                    DeleteUploadItem(
0);
                    
if(mUploadFiles.length>0)
                    intervalId
=flash.utils.setInterval(function(){
                            flash.utils.clearInterval(intervalId);
                            
                            Upload_File();
                        },
500,null);
                },function(){
                    rp.executeBindings(
true);
                });
            }

 上传的方法很简单就是从0索引开始上传,把上传完成的文件移走继续上传下一个直到列表上传完成,如果现在继添加上传文件也会排到队列后等待上传。

不过实际情况你可以同时上传多个的,只要对不同UploadFile调用Upload即可。

服务端代码

 对于采用什么样的服务端来完成文件处理就根据自己的喜好了,我用的是自己基于C#编写的http xml服务。

ContractedBlock.gifExpandedBlockStart.gifCode
    [ActionMapper]
    
public class FileUpload:Users.WebService.ActionBase
    {
        
public string Title
        {
            
get;
            
set;
        }
        
public NClay.File File
        {
            
get;
            
set;
        }
        
public int FolderID
        {
            
get;
            
set;
        }
        
protected override void OnExecute()
        {
            
base.OnExecute();
            Expression exp 
= Folder.folderID == FolderID & Folder.owner != Loginer.UserID;
            
if (Folder.Count(exp) > 0)
                
throw new Exception("无权在其他人的文件夹中添加文件!");
            
string filename = Guid.NewGuid().ToString() + System.IO.Path.GetExtension(File.Name);
            Files.File f 
= new File();
            f.Owner 
= Loginer.UserID;
            f.OwnerName 
= Loginer.UserName;
            f.FileName 
= filename;
            f.CreateDate 
= DateTime.Now;
            f.Title 
= Title;
            f.FolderID 
= FolderID;
            f.DownloadName 
= System.IO.Path.GetFileNameWithoutExtension(Title) + System.IO.Path.GetExtension(File.Name);
            f.Save();
            FileHandler.SaveFile(Loginer.UserName, f.FileName, File);
        }
        
protected override bool SigninAccess
        {
            
get
            {
                
return true;
            }
        }
    }

 

 实际应用效果图

 

 

 

 

 


 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值