2017-04-19 90 views
0

这个问题使我疯狂,我不知道我在这里错过了什么。这是我的代码:AS3:功能之外的访问变量

package { 
 
\t 
 
\t import flash.display.*; 
 
\t import flash.text.*; 
 
\t import flash.events.*; 
 
\t import flash.net.*; 
 
\t import flash.xml.*; 
 
\t 
 
\t public class PopUp extends Sprite { 
 
\t \t 
 
\t \t public var container:Array = new Array(); 
 

 
\t \t public function PopUp() { 
 
\t \t \t 
 
\t \t \t var contentXML:XML = new XML(); 
 
\t \t \t var XML_URL:String = "./content/content.xml"; 
 
\t \t \t var contentXMLURL:URLRequest = new URLRequest(XML_URL); 
 
\t \t \t var contentLoader:URLLoader = new URLLoader(contentXMLURL); 
 
\t \t \t contentLoader.addEventListener("complete", FuncXML); 
 
\t \t \t 
 
\t \t \t function FuncXML(event:Event):void { 
 
\t \t \t \t contentXML = XML(contentLoader.data); 
 
\t \t \t \t for each (var item in contentXML.item) { 
 
\t \t \t \t \t 
 
\t \t \t \t \t var txtbox:Sprite = new Sprite(); 
 
\t \t \t \t \t txtbox.graphics.beginFill(0x444444, 0.9); 
 
\t \t \t \t \t txtbox.graphics.drawRoundRect(0, 0, 100, 100, 15, 15) 
 
\t \t \t \t \t txtbox.graphics.endFill(); 
 
\t \t \t \t \t txtbox.name = "txtbox_"+item.settings.target; 
 
\t \t \t \t \t addChild(txtbox); 
 
\t \t \t \t \t container.push(txtbox); 
 
\t \t \t \t } 
 
\t \t \t \t trace(container.length); // Returns 2 
 
\t \t \t } 
 
\t \t trace(container.length); // Returns 0 
 
\t \t } 
 

 
\t } 
 
\t 
 
}

此代码应创建一个XML文件的内容文本框的最终版本,但我不能让含量超出了功能的“FuncXML ”。我试着跟踪。函数内部的轨迹返回“容器”的正确长度,即2。函数外部,轨迹返回0.请问这里有什么问题吗?

回答

3

正如其他答案中所解释的,您的第二个跟踪将在内函数的第一个跟踪之前执行。我发生这种情况是因为URLLoader不是即时的,需要一段时间才能加载数据。所以你必须等到它完成工作。您可以等待本文档中描述的特定事件:URLLoader Adobe Help。 下面我可以建议你可能想要做一些基本的例子:

public class PopUp extends Sprite { 

    public var container:Array = new Array(); 
    // Class constructor  
    public function PopUp() { 

    } 

    public function prepareAndLoad():void { 
     var XML_URL:String = "./content/content.xml"; 
     var contentXMLURL:URLRequest = new URLRequest(XML_URL); 
     var contentLoader:URLLoader = new URLLoader(); 
     contentLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete); 
     // good practice here would be to expect errors as well: 
     contentLoader.addEventListener(IOErrorEvent.IO_ERROR, onError); 
     contentLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); 

     contentLoader.load(contentXMLURL); 
    } 
    private function onError(e:ErrorEvent):void { 
     trace("Error"); 
     // maybe you want to handle this situation somehow. 
    } 

    private function onXMLLoadComplete(event:Event):void { 
     var contentXML:XML = XML(event.target.data); 
     for each (var item in contentXML.item) { 
      var txtbox:Sprite = new Sprite(); 
      txtbox.graphics.beginFill(0x444444, 0.9); 
      txtbox.graphics.drawRoundRect(0, 0, 100, 100, 15, 15) 
      txtbox.graphics.endFill(); 
      txtbox.name = "txtbox_"+item.settings.target; 
      addChild(txtbox); 
      container.push(txtbox); 
     } 
     trace(container.length); 
     // here your XML is loaded and processed. Dispatch an event to notify that job is done and container is not empty. 
     dispatchEvent(new Event(Event.COMPLETE)); 
    } 
} 

某处在你的项目,你可以创建这个弹出的一个实例:

//... 
var popUp:PopUp = new PopUp(); 
popUp.addEventListener(Event.COMPLETE, onPopUpReady); 
popUp.prepareAndLoad(); 
//... 
private function onPopUpReady(e:Event):void { 
    var popUp:PopUp = e.target as PopUp; 
    trace(popUp.container.length); // Ready and loaded. 
} 
//... 
+0

谢谢您的回答!但是我怎样才能从课堂外访问数组“容器”?我在我的主文件中试过: 'var newTxt:PopUp = new PopUp(); trace(newTxt.container.length); ' 但它再次返回0。 – patrickhoehn

+0

注意以上Andrea给出的答案。在你追踪数组长度为0时,因为你的XML尚未加载。 – Nbooo

+0

@patrickhoehn我已经更新了我的答案,请看看。希望它会有所帮助。 – Nbooo

2

读你的代码,我可以看到,第二个trace(container.length);仅返回0,因为它在之前被称为“第一个”trace(container.length);

你可以理解它,如果你看到这个函数FuncXML只申报并添加第二跟踪之前侦听器回调(或处理),但因为你是在异步环境下,你永远不会知道,如果FuncXML内容将在第二次“跟踪”调用之前执行。

特别是,您有两个并行运行的函数流:PopUpFuncXML流,但您认为它们是相应的。

希望这可以帮助你

-1

正如前面提到的,你正在寻找的项目之前加载它们。
你应该等到他们已经装好并准备好了,然后在舞台上或其他地方处理它们。

我会处理这种情况是这样的:
在您的主文件:

var newTxt:PopUp = new PopUp({ 
    onReady_func: handlePopUp //pass the function to PopUp class as a parameter 
}); 

// this function will be called whenever PopUp is ready 
function handlePopUp(){ 
    trace(newTxt.container.length); 
} 

在弹出类:

... 
// the $config object contains setup parameters 
public function PopUp($config) { 
    ... 
    function FuncXML(event:Event):void { 
     ... 
     // Everything is ready. Lets tell them. 
     $config.onReady_func(); // this call should be in the last line of funcXML 
    } 
+0

这里有一些'气味',imho:1 - 混合骆驼案例和下划线符号。 2 - 在JS风格中传递回调,而不是使用类型化参数。在这里使用回调而不是本地事件有什么意义? – Nbooo

+0

我不知道这2条规则。他们是个人的吗?如果没有,请提供一些参考。 – cameraman

+0

正如我所说,这绝对是基于观察和个人在多个相当大的项目中获得的经验的个人意见。 – Nbooo