Actionscript 3 - 如何在删除该事件后保留该事件的值

Posted

技术标签:

【中文标题】Actionscript 3 - 如何在删除该事件后保留该事件的值【英文标题】:Actionscript 3 - How to keep the value from an event after removing that event 【发布时间】:2012-01-12 18:19:06 【问题描述】:

我在我的事件处理函数(该函数在 event.COMPLETE 之后执行)期间以及如果我在我的事件中跟踪对象时为我的 xml 对象 (xml = new XML(e.currentTarget.data);) 设置了一个值函数处理程序,它显示我的 xml 数据。

但是如果我尝试在事件处理函数之外跟踪它,它不会显示我的 xml 内容。有没有办法让我的 xml 对象内容值显示在其他函数中但不在事件处理函数中?

private var xml:XML; 

public function XMLLoader(xmlURL:String) 
 
    var xmlURLRequest:URLRequest = new URLRequest(xmlURL); 
    var xmlURLLoader:URLLoader  = new URLLoader(xmlURLRequest); 
    xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 


private function xmlData(e:Event):void 

    e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
    xml = new XML(e.currentTarget.data); 
    dispatchEvent(new Event(Event.COMPLETE)); 
    trace(xml); 
 

public function getXMLData():void 
 
     //I've find out that this shows null because this function is faster
     //what do i do? put an event.complete in every following function?
    trace(xml);

谢谢。

【问题讨论】:

私有变量 xml:XML;公共函数 XMLLoader(xmlURL:String) var xmlURLRequest :URLRequest = new URLRequest(xmlURL); var xmlURLLoader :URLLoader = new URLLoader(xmlURLRequest); xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 私有函数 xmlData(e:Event):void e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); xml = 新 XML(e.currentTarget.data); dispatchEvent(新事件(Event.COMPLETE));跟踪(xml); 公共函数 getXMLData():void trace(xml); 您能否将代码发布到您实例化XMLLoader 并调用getXMLData() 方法? 公共类 XMLLoader 扩展 EventDispatcher private var xml:XML;公共函数 XMLLoader(xmlURL:String) var xmlURLRequest:URLRequest = new URLRequest(xmlURL); var xmlURLLoader:URLLoader = new URLLoader(xmlURLRequest); xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 私有函数 xmlData(e:Event):void e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); xml = 新 XML(e.currentTarget.data); dispatchEvent(新事件(Event.COMPLETE)); trace(xml);//这个显示 public function getXMLData():XML trace(xml); //这个不显示 您能否在您的问题中发布代码。这样它的可读性更高。但我想看到的是你在哪里调用getXMLData()new XMLLoader("xmlURL") 【参考方案1】:

我认为你在XMLLoader() 之后立即调用getXMLData(),此时xml 对象仍然为空。尝试调用getXMLData() inside xmlData() 函数,您应该会看到不同。

【讨论】:

事情甚至在这个“xml = new XML(e.currentTarget.data);”之后在事件处理程序中,当您想在事件处理程序之外跟踪 xml 时,该值不再存在,此时它为空,我希望它在 event.complete 之后需要时可以全局访问任何函数 在这种情况下,很难说出问题所在。你能把完整的代码发给XMLLoadergetXMLData吗? 我已经发布了正在发生的事情。看下面的帖子。谢谢^^【参考方案2】:

您可能在 URLLoader 完成之前调用 getXMLData() 但是,通常,您正在执行的代码是不好的做法。 Actionscript 没有任何阻塞,因此当您使用 URLRequest 实例化新的 URLLoader 时,它会立即开始加载操作。例如,如果您的文件被缓存,则您的 Event.COMPLETE 侦听器可能永远不会触发,因为您在开始加载操作后附加它。

我在下面附上了创建和加载数据的理想过程:

var data:XML;
var urlLoader:URLLoader = new URLLoader();

urlLoader.addEventListener(Event.COMPLETE, urlLoader_completeHandler);
urlLoader.load(new URLRequest("path"));

private function urlLoader_completeHandler(event:Event):void

    data = new XML(urlLoader.data);

如果你想把它应用到你自己的 XMLLoader 类中,我已经在 AS3 中包含了“正确”的实现......但是非常冗长。

import flash.net.URLLoader;
import flash.events.Event;

class XMLLoader extends URLLoader

    public function XMLLoader()
    
        super();
        addEventListener(Event.COMPLETE, completeHandler);
    

    private function completeHandler(event:Event):void
    
        dispatchEvent(new XMLLoaderEvent(XMLLoaderEvent.COMPLETE, new XML(data)));
    


class XMLLoaderEvent extends Event

    public static const COMPLETE:String = "xmlLoaderComplete";

    public var data:XML;

    public function XMLLoaderEvent(type:String, data:XML = null, bubbles:Boolean = false, cancelable:Boolean = false)
    
        super(type, bubbles, cancelable);

        this.data = data;
    

    override public function clone():Event
    
        return new XMLLoaderEvent(type, data, bubbles, cancelable);
    

使用 XMLLoader 类:

var xmlLoader:XMLLoader = new XMLLoader();
xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, function(event:XMLLoaderEvent):void

    trace(event.data);
);

xmlLoader.load(new URLRequest("data.xml"));

祝你好运!

【讨论】:

我不同意这是不好的做法。当您将响应者添加到 HTTPRequest 或 RemoteObject 时,您甚至在调用 send() 之后才能访问令牌,这就是您实际添加响应者的内容。只要您不调用方法主体中的任何函数(或调度任何导致函数被调用 elswhere 的事件),在下一行附加您的侦听器或响应器就可以了。另请注意,没有理由仅仅为了定义一个 Event 常量而创建一个新的 Event 类型(并且 URLLoader 拥有它需要的所有事件)。 @stat 这就是我的意思;你看到你的第一个代码,打开任何 xml 文件的正确代码?我希望数据对象即使在函数“urlLoader_completeHandler”之后也能保留 xml 内容,所以在“data = new XML(urlLoader.data);”之后即使“urlLoader_completeHandler”函数之外的跟踪数据也是可以访问的,但如果我在该函数之外跟踪数据,它会显示为空。没有解决办法吗?所以每次我需要访问数据时,我都必须通过 event.complete? 我现在将看到代码的第二和第三部分,我会告诉你一些事情,但我所说的第一个 sa 给出的结果与我的代码相同。欢呼【参考方案3】:

更改您的跟踪方法以指示 xml 是否已加载... 你遇到了竞争状况

private var _xmlLoaded:Boolean=false;// add this to see if the xml is loaded
private function xmlData(e:Event):void 

    e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
    xml = new XML(e.currentTarget.data); 
    _xmlLoaded=true;
    dispatchEvent(new Event(Event.COMPLETE)); 
    trace(xml); 
 
public function getXMLData():void 
 
    if (_xmlLoaded)
        trace(xml);
    else
        trace("not yet loaded");

【讨论】:

我认为你得到了我所要求的,我会尽快测试代码并告诉你一些事情。干杯【参考方案4】:

//注意:如果你想直接访问这个“类”的函数而不使用任何事件监听器,请使用它,因为它已经在每个函数上都有它的事件监听器(这会导致一个函数只有 getXMLData() )

私有变量 xml:XML;

公共函数 XMLLoader(xmlURL:String)

     var xmlURLRequest:URLRequest = new URLRequest(xmlURL); 
     var xmlURLLoader:URLLoader  = new URLLoader(xmlURLRequest); 
     xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 

私有函数 xmlData(e:Event):void

     e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
     xml = new XML(e.currentTarget.data); 
     dispatchEvent(new Event(Event.COMPLETE)); 
     trace("1");//this used to come second of getXMLData() but it's solved now
     trace(xml); 

公共函数 getXMLData():void

     //This function was coming first so if you don't want to use an event listener outside    
     //this class to wait for event.complete you can use it here to wait for it and access
     //the function directly without being afraid of the object being null:
     addEventListener(Event.COMPLETE, go)
     function go(e:Event)
          trace("2"); //now it ONLY comes AFTER the event.complete, no need for external                   listeners over this class. declare the class object and use getXMLData() directly cause it always comes second the event handler xmlData() :)
          trace(xml);
     

【讨论】:

以上是关于Actionscript 3 - 如何在删除该事件后保留该事件的值的主要内容,如果未能解决你的问题,请参考以下文章

Actionscript 3 Flash 键盘事件

Flash ActionScript 3.0 调整事件文本大小

如何检测 Actionscript 3 中是不是按下了删除键?

在 actionscript 3 中使用多个或仅一个事件监听器

(ActionScript 3.0)我的函数没有通过按钮事件更新全局变量

Actionscript 3 - 如何删除菜单栏、滚动条以仅显示空白弹出窗口?