0

我正在尝试使用 Apache Flex SDK 4.12.1 使用 Flex 模块对模块化应用程序架构进行原型设计。我有以下项目结构。

  1. CommonLib 弹性库。该项目包含一个文件,IPlugin.,如下所示。

    {
        import mx.core.IVisualElement;
    
        public interface IPlugIn
        {
            function get MyPlugin():IVisualElement;
        }
    }
    
  2. ModuleProject 弹性应用程序。该项目包含两个文件。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>
    
  3. FlexProject 弹性应用项目。这包含一个文件,目的是将 PluginModuleDemoForm.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>
    

我可以将模块直接添加到应用程序的容器中,一切似乎都正常。然后应用程序容器将显示由 PluginModule.mxml 实现的 1 按钮。但是,当我尝试通过 plugin.MyPlugin 方法将 Demoform 添加到应用程序的容器时,我收到以下错误。

错误:无法找到 FlexProject.ApplicationSkin2.containerGrp.contentGroup.VBox5.container.BorderContainerSkin10.Group11.DemoForm13.RadioButton16 的皮肤。

我已经尝试了许多不同的控件,包括 TextArea、TextInput 和 RadioButtons。这些都因类似的错误而失败。似乎主应用程序找不到这些组件的皮肤!

有趣的是,如果我改为允许 PluginModule.mxml 将 DemoForm.mxml 添加到它自己的容器中,它就可以正常工作。虽然,这不是我想要的行为。

关于可能发生的事情以及我如何解决它的任何建议?

4

2 回答 2

0

我认为您的模块省略了必需的类,这些在主应用程序中也不可用。

如果您希望包含未使用的类,则对这些类使用导入就足够了。确保将导入包含在正在使用的类中。

添加编译器标志“链接报告文件名”生成报告以查看包含哪些类。

于 2014-12-09T08:26:11.347 回答
0

一位同事找到了答案。在将加载您需要添加-keep-all-type-selectors到编译器选项的模块的项目中。根据adobe 文档...

-保留所有类型选择器

指示编译器将样式表的类型选择器保留在 SWF 文件中,即使该类型(类)未在应用程序中使用。当您有一个加载其他应用程序的模块化应用程序时,这很有用。例如,加载 SWF 文件可能会为加载(或目标)SWF 文件中使用的类型定义类型选择器。如果在编译加载 SWF 文件时将此选项设置为 true,则目标 SWF 文件将在加载时访问该类型选择器。如果将此选项设置为 false,则编译器将不会在编译时在加载 SWF 文件中包含该类型选择器。因此,这些样式将不适用于目标 SWF 文件。

这是一个高级选项。

于 2014-12-09T13:35:28.440 回答