Question

I'm creating a simple Flash project with Flash CS5 and ActionScript 3.

What I want to do is that I want to dynamically update a TLF text container with given source and destination, something like loadData(text_placeX, "markup.xml"); anywhere that I want.

It's working like a charm, but the problem is I can't use any scroll-bar for my text. I have added a UIScrollBar to text container and it's working with the default text that I've putted into text container, but when I update container with my data it's not working. What am I missing?

Another question is that how I can empty my text container before loading new data in it?

My code is:

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();
}

UPDATE: When I skip using of initText function contents and instead I use text_place.tlfMarkup = fileContent; it works; but my option on TextFlow is missing. And also I was missing "update scrollbar" after putting content in text-field.

Was it helpful?

Solution

I think this line may be the problem:

ldr.addEventListener(Event.COMPLETE, function(evt:Event){ ldr_complete(text_place) }, false, 0, true);

You have an anonymous function here (function(evt:Event){...) which passes the object text_place to the function ldr_complete(). However, you do not have access to text_place, since it is a variable declared within a different scope. If you make the function into a named one, you will not assume that you have that access. E.g.,

function loadCompleteHnd(evt:Event):void{
[...]
}

However, you still have to gain access to the object in text_place. So, you can make text_place a class-level (global) variable, and set that variable whenever. But that may run the risk of creating a race condition -- if you have a slow load, you might be trying change that object from two places at once.

Another option is to create an entirely new Event which extends the Event.COMPLETE setup. At that point, you can create another parameter for the Event.COMPLETE listener to use. This is complicated, and a bit of a learning curve, but it makes events more versatile.

In either case, you may want to set up a flag that tells you whether something else is editing the same object. It's not foolproof, but it can save some headaches.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top