Ошибка: обложка для xxx не может быть найдена при добавлении IVisualElement, полученного из модуля Flex через пользовательское свойство
Я пытаюсь создать прототип модульной архитектуры приложений с использованием Apache Flex SDK 4.12.1 с использованием модулей Flex. У меня есть следующая структура проекта.
CommonLib flex библиотека. Этот проект содержит один файл IPlugin.as, как показано ниже.
{ import mx.core.IVisualElement; public interface IPlugIn { function get MyPlugin():IVisualElement; } }
Модуль FlexProject. Этот проект содержит два файла. PluginModule.mxml - модуль, который я хочу загрузить, и DemoForm.mxml - компонент, который я хочу добавить в основное приложение.
// PluginModule.mxml <?xml version="1.0" encoding="utf-8"?> <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*" implements="Interfaces.IPlugIn"> <fx:Script> <![CDATA[ import mx.core.IVisualElement; private var _myPlugin:DemoForm = new DemoForm(); protected function button1_clickHandler(event:MouseEvent):void { container.addElement(new DemoForm()); } public function get MyPlugin():IVisualElement { if (_myPlugin == null) _myPlugin = new DemoForm(); return _myPlugin; } ]]> </fx:Script> <s:HGroup> <s:Button id="btn" label="Add DemoForm" click="button1_clickHandler(event)"/> <s:VGroup id="container"/> </s:HGroup> </s:Module> // Demoform.mxml <?xml version="1.0" encoding="utf-8"?> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400"> <s:layout> <s:TileLayout/> </s:layout> <s:Button label="Button 1"/> <s:TextInput/> </s:Group>
FlexProject проект гибкого приложения. Он содержит один файл с намерением загрузить PluginModule и DemoForm.mxml в его BorderContainer.
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Script> <![CDATA[ import mx.core.IVisualElement; import mx.events.ModuleEvent; import mx.modules.IModuleInfo; import mx.modules.ModuleManager; import Interfaces.IPlugIn; private var moduleInfo:IModuleInfo; protected function button1_clickHandler(event:MouseEvent):void { moduleInfo = ModuleManager.getModule("PluginModule.swf"); moduleInfo.addEventListener(ModuleEvent.READY, renderModule); moduleInfo.load(null, null, null, this.moduleFactory); } private function renderModule(event:ModuleEvent):void { var module:Object = moduleInfo.factory.create(); var plugin:IPlugIn = module as IPlugIn; container.addElement(plugin as IVisualElement); // <-- Works! container.addElement(plugin.MyPlugin); // <-- Error: Skin cannot be found } ]]> </fx:Script> <mx:VBox> <s:Button click="button1_clickHandler(event)" label="Add Plugin"/> <s:BorderContainer id="container"> <s:layout> <s:VerticalLayout gap="10"/> </s:layout> </s:BorderContainer> </mx:VBox> </s:Application>
Я могу добавить модуль непосредственно в контейнер приложения, и все, кажется, работает. Контейнер приложения отобразит кнопку 1, реализованную PluginModule.mxml. Однако, когда я пытаюсь добавить Demoform в контейнер приложения с помощью метода plugin.MyPlugin, я получаю следующую ошибку.
Ошибка: обложка для FlexProject.ApplicationSkin2.containerGrp.contentGroup.VBox5.container.BorderContainerSkin10.Group11.DemoForm13.RadioButton16 не найдена.
Я пробовал это с многочисленными различными элементами управления, включая TextArea, TextInput и RadioButtons. Все они терпят неудачу с похожими ошибками. Похоже, что основное приложение не может найти скины для этих компонентов!
Интересно, что если я вместо этого позволю PluginModule.mxml добавить DemoForm.mxml в свой собственный контейнер, он будет работать нормально. Хотя, это не то поведение, которое я желаю.
Любые предложения относительно того, что может происходить и как я могу решить это?
2 ответа
Коллега нашла ответ. В проект, который будет загружать модули, нужно добавить -keep-all-type-selectors
к параметрам компилятора. Согласно Adobe Docs...
-keep-все-типа-селекторы
Указывает компилятору сохранить селектор типа таблицы стилей в SWF-файле, даже если этот тип (класс) не используется в приложении. Это полезно, когда у вас есть модульное приложение, которое загружает другие приложения. Например, загружаемый SWF-файл может определять селектор типа для типа, используемого в загруженном (или целевом) SWF-файле. Если вы установите для этого параметра значение true при компиляции загружаемого SWF-файла, то целевой SWF-файл будет иметь доступ к этому селектору типов при его загрузке. Если для этого параметра установлено значение false, компилятор не будет включать этот селектор типа в загружаемый SWF-файл во время компиляции. В результате стили не будут доступны для целевого SWF-файла.
Это расширенный вариант.
Я думаю, что ваш модуль пропускает обязательные классы, и они не доступны в основном приложении.
Если вы хотите, чтобы неиспользуемые классы были включены, достаточно использовать импорт для этих классов. Убедитесь, что вы включили импорт в используемый класс.
Добавление флага компилятора "link-report filename" создает отчет, чтобы увидеть, какие классы включены.