我在舞台上添加了一些标签,每个标签都会加载自己的swf文件。我有一个数组跟踪选项卡,但需要知道每个swf何时加载它所属的选项卡。我不确定最好的方法。
标签由XML控制,因此可以有任意数量的标签 -
for (var j = 0; j < _xmlTabs.length(); j++) {
arrTabs[j] = new Tab(j,_xmlTabs[j].attribute("icon"),_xmlTabs[j]);
addChildAt(arrTabs[j],0);
mRequest = new URLRequest(_xmlTabs[j].attribute("swf"));
mLoader = new Loader();
addChild(mLoader);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTabComplete);
mLoader.load(mRequest);
}
好吧,假设有5个标签正在加载,每个标签加载自己的swf,“onTabComplete()”被触发5次。即使按顺序创建每个选项卡,onTabComplete也可能无法按顺序触发,因为swfs的大小不同。那么如何将每个选项卡与onTabComplete函数相关联?每个实例化的Tab项都有一个可以检索的“position”属性。
答案 0 :(得分:3)
使用自定义类扩展Loader类,添加所需的新属性,然后可以将其引用为
e.currentTarget.loader.newproperty
在事件处理程序
中答案 1 :(得分:1)
我认为thehiatus's answer的修改版本应该绕过共享问题的j值:
function buildHandleComplete(i:int):Function {
return function(event:Event):void {
onTabComplete(event, i);
};
}
for (var j:int = 0; j < _xmlTabs.length(); j++) {
arrTabs[j] = new Tab(j,_xmlTabs[j].attribute("icon"),_xmlTabs[j]);
addChildAt(arrTabs[j],0);
mRequest = new URLRequest(_xmlTabs[j].attribute("swf"));
mLoader = new Loader();
addChild(mLoader);
var handleComplete:Function = buildHandleComplete(j);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
mLoader.load(mRequest);
}
通过使用一个函数,该函数将索引值作为参数并使用它构建监听器,最后每个闭包引用一个不同的变量,而不是它们都引用j值。
答案 2 :(得分:0)
我不熟悉Tab类,但Tab是否扩展了DisplayObjectContainer?你可以做到:
arrTabs[j].addChild(mLoader);
然后在事件处理程序调用中:
e.currentTarget.parent.position
获取加载了哪个标签的指标,然后可能正确处理?
答案 3 :(得分:0)
为什么不用各自的网址识别它们?
private function onTabComplete(e:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(e.target);
trace(loaderInfo.url);
//btw, loaderInfo.content is the tab that you are looking for.
var url:String = loaderInfo.url;
var tabIndex:Number;
for(var j:Number = 0; j < _xmlTabs.length(); j++)
{
if(url == String(_xmlTabs[j].attribute("swf")))
{
tabIndex = j;
break;
}
}
//tabIndex now contains the required "j"
}
编辑:如果标签加载相同的swfs(相同的网址)。
即使这样做,你也应该考虑重新设计。
private function onTabComplete(e:Event):void
{
int total:Number = _xmlTabs.length();
var loader:Loader = LoaderInfo(e.target).loader;
var p:DisplayObjectContainer = loader.parent;
if(p.numChildren != total * 2)
{
trace("other children present : this method won't work");
return;
}
var ldrIndex:Number = p.getChildIndex(loader);
var tabIndex:Number = ldrIndex - total;
var matchingTab:Tab = arrTabs[tabIndex];
//enjoy
}
答案 4 :(得分:0)
AS3也支持匿名函数,所以你可以这样做:
addChild(mLoader);
var handleComplete:Function = function(event:Event):void {
onTabComplete(event, j);
};
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
mLoader.load(mRequest);
答案 5 :(得分:0)
根据我的经验,您需要设置加载队列。一次加载一个将防止一些潜在的错误
private var j:int = 0; // currentTab number
private function loadNextTab():void{
arrTabs[j] = new Tab(j,_xmlTabs[j].attribute("icon"),_xmlTabs[j]);
addChildAt(arrTabs[j],0);
mRequest = new URLRequest(_xmlTabs[j].attribute("swf"));
mLoader = new Loader();
addChild(mLoader);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTabComplete);
mLoader.load(mRequest);
}
private function onTabComplete():void{
_xmlTabs[j].attribute("position")
//Anything else you want to do to instantiate the object.
currentTab++
loadNextTab();
}
没有回答关于传递变量的问题,
它确实回答了我建议你对代码做的事情。
传递变量:
一种常见的方法是“自定义事件”
http://flexcomps.wordpress.com/2008/04/29/dispatching-custom-events-in-as3-with-data-or-object/
创建一个扩展Event的类,然后将一个数据对象添加到Event中。然后,您需要包含的任何数据都需要发送到数据对象。
其他一些方法包括:
匿名函数如thehiatus解释
//errors inside anonymous functions are harder to debug.
和嵌套函数
private function startLoad():void{
var j:int = 0;
//load request calling LoadComplete
funciton LoadComplete(e:Event){
//has access to j
//errors inside nested functions are harder to debug.
}
}
但这些方法也不适用于你的for循环。您要访问的数据可通过索引访问,但您的for循环在任何完成加载之前都会通过索引。加载队列是解决当前问题的方法。
祝你好运。答案 6 :(得分:0)
这是一个快速的解决方案! 你可以使用Dictionary对象。
var d:Dictionary=new Dictionary;
for (var j = 0; j < _xmlTabs.length(); j++) {
arrTabs[j] = new Tab(j,_xmlTabs[j].attribute("icon"),_xmlTabs[j]);
addChildAt(arrTabs[j],0);
mRequest = new URLRequest(_xmlTabs[j].attribute("swf"));
mLoader = new Loader();
//associate a tab with his loader...
d[mLoader]=arrTabs[j];
//
addChild(mLoader);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTabComplete);
mLoader.load(mRequest);
}
//
function onTabComplete(e:Event):void{
trace("your tab TAB >",d[e.target]);
}
答案 7 :(得分:0)
将每个加载器与选项卡相关联(选项卡具有指向加载程序的链接),然后使用事件中的.target成员获取已完成的加载程序,然后遍历选项卡以查找具有该加载程序关联的选项卡。
如果您还没有正确地提供它来保存对加载器的引用,您可能必须创建自己的选项卡类。
我做了一个类似的例子来加载外部资源并跟踪他们的进度。