我正在用Flash CS5和ActionScript 3创建一个简单的Flash项目。
我想做的是,我想动态更新具有给定源和目的地的TLF文本容器,类似于loadData(text_placeX, "markup.xml");
。
它很有魅力,但问题是我不能用任何滚动条来显示文本。我在文本容器中添加了一个UIScrollBar
,它使用我放入文本容器中的默认文本,但当我用数据更新容器时,它不起作用。我错过了什么?
另一个问题是,如何在加载新数据之前清空文本容器?
我的代码是:
import fl.text.TLFTextField;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.text.TextFieldAutoSize;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.conversion.TextConverter;
import fl.controls.ScrollBar;
var ldr:URLLoader = new URLLoader();
var flow:TextFlow = new TextFlow();
function loadData(text_place, fileURL:String):void {
text_place.border = true;
ldr.dataFormat = URLLoaderDataFormat.TEXT;
ldr.addEventListener(Event.COMPLETE, function(evt:Event){ ldr_complete(text_place) }, false, 0, true);
ldr.load(new URLRequest(fileURL));
ldr.addEventListener(IOErrorEvent.IO_ERROR, loadError);
}
function ldr_complete(text_place:TLFTextField):void {
ldr.removeEventListener(Event.COMPLETE, ldr_complete);
ldr.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
initText(text_place, ldr.data);
}
function loadError(e:IOErrorEvent):void {
trace("Error loading an external file. The server may be busy. Try refreshing the page.");
}
function initText(text_place:TLFTextField, fileContent):void {
flow = TextConverter.importToFlow(fileContent, TextConverter.TEXT_FIELD_HTML_FORMAT);
flow.flowComposer.addController(new ContainerController(text_place, text_place.width, text_place.height));
flow.flowComposer.updateAllControllers();
}
更新:当我跳过使用initText
函数内容,而使用text_place.tlfMarkup = fileContent;
时,它会起作用;但我在TextFlow
上的选项丢失了。而且在将内容放入文本字段后,我还缺少了"更新滚动条"。
我认为这一行可能是问题所在:
ldr.addEventListener(Event.COMPLETE, function(evt:Event){ ldr_complete(text_place) }, false, 0, true);
这里有一个匿名函数(function(evt:Event){...
),它将对象text_place
传递给函数ldr_complete()
。但是,您不能访问text_place
,因为它是在不同范围内声明的变量。如果您将函数设置为命名函数,则不会认为您具有该访问权限。例如,
function loadCompleteHnd(evt:Event):void{
[...]
}
但是,您仍然需要访问text_place
中的对象。因此,您可以将text_place
设置为类级(全局)变量,并随时设置该变量。但这可能会产生竞争条件的风险——如果你的负载很慢,你可能会尝试同时从两个地方更改该对象。
另一种选择是创建一个全新的Event
,它扩展了Event.COMPLETE
设置。此时,您可以为Event.COMPLETE
侦听器创建另一个要使用的参数。这很复杂,有点像一条学习曲线,但它使事件更加多样化。
在任何一种情况下,您都可能需要设置一个标志来告诉您是否有其他对象正在编辑同一对象。这不是万无一失的,但它可以省去一些麻烦。