使用自定义LoaderInfo类的自定义AS3 Loader类?

问题描述:

这是一个关于创建自定义装载程序类的问题,作为How do I modify existing AS3 events so that I can pass data?的后续操作。如果这不是解决这个问题的正确方法,请告诉我。使用自定义LoaderInfo类的自定义AS3 Loader类?

我有一个自定义的Loader类和一个自定义的LoaderInfo类。我无法弄清楚的是如何让Loader类使用自定义LoaderInfo类,因为它的contentLoaderInfo属性。

package com.display { 
    import flash.display.Loader; 

    import com.display.CustomLoaderInfo; 

    public class CustomLoader extends Loader { 
     public var customData:*; 

     public function CustomLoader(passedData: *= null) { 
      customData = passedData; 
     } 
    } 
} 

^要做的东西在里面,使之具有新的CustomLoaderInfo

package com.display { 
    import flash.display.LoaderInfo;  
    import flash.events.Event; 

    import com.events.CustomEvent; 

    public class CustomLoaderInfo extends LoaderInfo { 
     public var customData:*; 

     public function CustomLoaderInfo(passedData: *= null) { 
      customData = passedData; 
     }  

     override public function dispatchEvent(event:Event):Boolean { 
      var customEvent:CustomEvent = new CustomEvent(event.type, customData, event.bubbles, event.cancelable); 
      return super.dispatchEvent(customEvent); 
     } 
    } 
} 

^可能的工作,但因为我不能让CustomLoader使用它,我不知道然而。

+0

这将无法正常工作,因为您无法继承LoaderInfo,它会抛出错误#2012:CustomLoaderInfo类无法实例化。 – Wernight 2014-01-13 15:35:48

我不知道它如何适合你在做什么,但你根本无法制作一个扩展的LoaderInfo。 Loader.contentLoaderInfo有一个名为loader的属性,它将返回使用的Loader(或本例中为CustomLoader)。理论上你可以做到这一点跟你有CustomLoader类:


var loader: CustomLoader = new CustomLoader("Extra Data"); 
loader.load(new URLRequest("file.swf")); 
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete); 

function loaderComplete(event: Event) : void 
{ 
    var customData:* = (event.target.loader as CustomLoader).customData; 
    trace(customData); // Extra Data 
} 

您将不得不重写创建loaderinfo实例的函数,该函数可能位于私有函数中。在新函数中,您可以实例化您的自定义loaderInfo类,但是您也必须执行覆盖的方法所做的任何其他操作。您也可能会遇到一些loadinfo安全沙箱问题。覆盖这样的函数通常只有在写出这个函数时才是可行的。

或者,您可以使用原型链(read here)在运行时更改loaderInfo类。但我不会推荐它。我认为这不是一个好习惯。

如果你得到这个工作,你仍然有问题,你的自定义事件不适用于任何具有不是从Event类继承的属性的事件(如ProgressEvent具有与进度相关的属性)。

我会说你应该寻找另一种解决方案。 在链接到您的问题中,您将讨论如何向您的活动发送影片剪辑。你有没有想过达到另一种方式?当你收到事件时,你会得到一个指向它的对象的引用(Event.target)。你不能使用该参考来获取动画片段吗?

也许你可以更详细地解释你的问题(也许在一个新的问题,所以你仍然保持这个开放),我相信有一个更好/更简单的方法来解决它。

我需要的是这样的,因为我想携带的指数与信息...也就是 - 有这样的事event.target.index可用事件被触发后..反正我设计了包含装载机和装载机信息类...继承人的类

公共类LoaderBox扩展Sprite {

public static var PROGRESS:String = "progress" 
    public static var COMPLETE:String = "complete" 

    public var id:int 
    public var index:int 
    public var loader:Loader 
    public var info:LoaderInfo 
    public var isOpen:Boolean 
    // 
    public var percent:Number = -1 

    public function load(path:String,idx:int=-1,nm:String=null){ 
     loader = new Loader() 
     if (nm != null){ 
      name = nm 
     } 
     index = idx 
     var req:URLRequest = new URLRequest(path) 
     info = loader.contentLoaderInfo 
     info.addEventListener(Event.COMPLETE,complete) 
     info.addEventListener(ProgressEvent.PROGRESS,progress) 
     isOpen = true 
     loader.load(req) 
    } 
    private function complete(e:Event):void{ 
     isOpen = false 
     dispatchEvent(new Event(LoaderBox.COMPLETE)) 
    } 
    private function progress(e:ProgressEvent):void{ 
     if (e.target.bytesTotal>0){ 
      percent = Math.floor(e.target.bytesLoaded/e.target.bytesTotal * 100) 
     } 
     dispatchEvent(new Event(LoaderBox.PROGRESS)) 
    } 

}

带标记答案的潜在问题:如果contentLoaderInfo吐出IOError,则无法访问.loader属性以访问您的自定义加载程序类。

我所做的是以下几点: *在我的自定义loader类,创建以下方法:

public function requestError(event:Event):void { 
     dispatchEvent(event);   
    } 

添加监听到的contentLoaderInfo为ioError在,指向自定义的加载类的方法:

_loaderCls.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _loaderCls.requestError); 

然后,将相同的侦听器添加到您的加载器类,并使其调用您需要的任何方法。在这一点上,event.target将是您的自定义类加载器的,你可以添加你需要的那类的任何额外的信息:

_loaderCls.addEventListener(IOErrorEvent.IO_ERROR, requestError); 

或者你可以做一个更好的事情将数据传递到Loader类:


package com.display 
{ 
    import flash.display.Loader; 

    public class Loader extends flash.display.Loader 
    { 
     private var _obj:Object; 

     public function Loader():void 
     { 
      super(); 
     } 

     public function get obj():Object 
     { 
      return _obj; 
     } 

     public function set obj(o:Object):void 
     { 
      _obj = o; 
     } 
    } 

}