Назначение типизированным переменным через разрывы границ SWF - PullRequest
0 голосов
/ 30 января 2012

Я пишу приложение, в котором используются расширяемые элементы пользовательского интерфейса, точная реализация которого определяется во время выполнения с использованием конфигурации. Так, например, я хочу показать список элементов, которые - в зависимости от конфигурации - могут отображаться в виде маркированного списка, нумерованного списка, списка из двух столбцов и т. Д. Содержащее приложение ничего не знает о конкретной реализации, за исключением того, что оно тип, который поддерживает вызов метода setItems(items:Array):void.

Итак, я настроил базовый класс, например:

package my.stuff {
    public class BaseList extends MovieClip {
        protected var m_items:Array;
        public function BaseList() {
            m_items = new Array();
        }
        public function setItems(items:Array):void {
            for (var i:int = 0; i < items.length; i++)
                m_items.push(items[i]);
        }
    }
}

А затем я создал специализированную реализацию, которая, например, делает список из двух столбцов:

package my.stuff {
    public class TwoColumnList extends BaseList {
        protected var m_columns:Array;
        public function TwoColumnList() {
            super();
            m_columns = new Array();
            m_columns.push(new Array());
            m_columns.push(new Array());
        }
        public override function setItems(items:Array):void {
            for (var i:int = 0; i < items.length; i++) {
                m_items.push(items[i]);
                m_columns[i%2].push(items[i]);
            }
        }
    }
}

Теперь сам пользовательский интерфейс выполняется во Flash Professional как FLA с классом TwoColumnList в качестве «класса документа». Я компилирую FLA («публикация») в целевой SWF, затем пытаюсь загрузить его в приложение. Обычно я ожидаю, что это будет работать так:

public function startLoading(implURL:String):void) {
    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.INIT, doneLoadingImpl);
    loader.load(new URLRequest(implURL));
}

public function doneLoadingImpl(e:Event) {
    var info:LoaderInfo = e.target as LoaderInfo;
    var impl:DisplayObject = info.content;
    m_containerClip.addChild(impl);
    var listImpl:BaseList = impl as BaseList;
    impl.setItems(m_allItems);
}

За исключением того, что это не работает - addChild() работает нормально, но приведение к BaseList приводит к null (не исключение - просто null). Я могу просто преобразовать impl в MovieClip, и я также могу преобразовать его в каталог TwoColumnList, после чего он будет красиво преобразован в BaseList, например:

...
var listImpl:BaseList = impl as TwoColumnList;
...

Так что это работает, но в действительности это наносит ущерб цели всего упражнения, а именно , а не , заранее знает конкретные реализации пользовательского интерфейса, которые могут быть созданы в будущем.

Я где-то читал о выполнении info.applicationDomain.getDefinition, но я не могу сказать, что это как-то влияет.

Я не являюсь разработчиком ActionScript в своей повседневной работе, меня только что вызвали на помощь в какой-то проект, чей основной разработчик больше не работает в компании, и я в замешательстве - любая помощь будет оценена .

1 Ответ

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

Ваша проблема, скорее всего, связана с загрузкой классов в разные домены приложения.Тип cast возвращает нуль, если объект не является подклассом класса, к которому вы приводите - и, кажется, у вас есть две версии BaseList, «конкурирующих» друг с другом.

В этом случае вы можете обойти эту проблему, явно загрузив SWF-файл в тот же домен приложения, что и основной:

 var ldrContext : LoaderContext = new LoaderContext ( false, ApplicationDomain.currentDomain );
 var loader:Loader = new Loader();
 loader.contentLoaderInfo.addEventListener(Event.INIT, doneLoadingImpl);
 loader.load(new URLRequest(implURL), ldrContext );

Однако, особенно при загрузке внешнего контента, выдолжен действительно использовать интерфейсы.Поддержание развязки реализаций - это именно то, для чего они были изобретены.Прочтите эту страницу блога, она объясняет, почему вы должны использовать интерфейсы при загрузке внешних файлов (там также есть ссылка на более фундаментальную информацию об интерфейсах), и, кстати, автор, похоже, столкнулся с проблемой, подобнойтвой ...;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...