Полоса прокрутки не работает с текстом TLF с динамическим содержимым в ActionScript 3 - PullRequest
0 голосов
/ 13 января 2012

Я создаю простой проект Flash с Flash CS5 и ActionScript 3.

Я хочу динамически обновлять текстовый контейнер 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 отсутствует. А также я пропустил «обновить полосу прокрутки» после помещения содержимого в текстовое поле.

1 Ответ

1 голос
/ 15 января 2012

Я думаю, что эта строка может быть проблемой:

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.Это сложный процесс, немного напоминающий процесс обучения, но он делает события более универсальными.

В любом случае вы можете захотеть установить флаг, который сообщит вам, что-то еще редактирует тот же объект.Это не надежно, но это может спасти некоторые головные боли.

...