Flex:引用模块内的组件 ID、嵌套视图堆栈等

发布于 2024-10-09 04:07:27 字数 801 浏览 9 评论 0原文

Adobe 文档指出:

MXML 组件中所有标记的 ID,无论嵌套的深度如何,都会生成所定义组件的公共变量。因此,文档中的所有 id 属性必须是唯一的。这也意味着,如果您为组件实例指定了 ID,则可以从应用程序中的任何位置访问该组件:从函数、外部类文件、导入的 ActionScript 文件或内联脚本。

全部包含在一个 MXML 中,但我在引用模块内的组件 ID 以及给定模块内的 ViewStack/导航容器内时遇到问题。

例如,

如果我可以使用 FlexGlobals.topLevelApplication.myModule 引用模块,那么我是否应该能够使用以下内容引用名为 myModulePanel 的面板?

FlexGlobals.topLevelApplication.myModule.myModulePanel

或者至少

FlexGlobals.topLevelApplication.myModule.getChildByName(myModulePanel)

对于标题、宽度等属性?

由于组件 ID 是公共变量(根据文档),我认为我不必链接一系列 .getChildByName() 函数来深入到组件/容器级别来访问组件属性,但是我的方法上面的尝试似乎不起作用。

但如果是这种情况,我真的需要形成一个长的组件引用链来访问 ViewStacks 等的子级,那么检查这个层次结构的最佳方法是什么?

任何建议将不胜感激。

谢谢。

The Adobe docs state:

The IDs for all tags in an MXML component, no matter how deeply nested they are, generate public variables of the component being defined. As a result, all id properties must be unique within a document. This also means that if you specified an ID for a component instance, you can access that component from anywhere in the application: from functions, external class files, imported ActionScript files, or inline scripts.

Which is fine if your application is all contained within one MXML, but I'm having trouble referencing IDs of components within Modules, and then inside ViewStacks/Navigation Containers within a given Module.

For instance,

If I can reference a module with FlexGlobals.topLevelApplication.myModule, shouldn't I be able to reference a Panel called myModulePanel with the following?

FlexGlobals.topLevelApplication.myModule.myModulePanel

or at least

FlexGlobals.topLevelApplication.myModule.getChildByName(myModulePanel)

for properties such as title, width etc?

Since component IDs are public variables (according to the docs), I didn't think I'd have to chain a series of .getChildByName() functions to drill down into component/container levels to access component properties, but the methods I've tried above don't seem to be working.

But if this is the case, do I really need to form a long chain of component references to access the children of ViewStacks etc then- and what is the best way to inspect this hierarchy?

Any suggestions would be greatly appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

穿透光 2024-10-16 04:07:27

您应该为每个模块创建一个接口(或所有模块都订阅的一个主接口),定义需要在模块外部调用的方法。这样,您与接口交互,而不是与模块本身交互,而是接口方法在模块类和主应用程序之间进行中介。

使用由 ModuleManager 加载的 IModuleInfo 接口应该可以帮助您实现这一点。有关详细信息,请参阅此页面

<?xml version="1.0"?>
<!-- modules/ModuleLoaderApp.mxml -->
<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"
    creationComplete="initApp()">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script>
        <![CDATA[
        import mx.events.ModuleEvent;
        import mx.modules.ModuleManager;
        import mx.modules.IModuleInfo;        
        import mx.core.IVisualElement;

        public var info:IModuleInfo;

        private function initApp():void {
            info = ModuleManager.getModule("ColumnChartModule.swf");
            info.addEventListener(ModuleEvent.READY, modEventHandler);           

            /* Load the module into memory. Calling load() makes the
               IFlexModuleFactory available. You can then get an
               instance of the class using the factory's create()
               method. */
            info.load(null, null, null, moduleFactory);
        }

        /* Add an instance of the module's class to the display list. */        
        private function modEventHandler(e:ModuleEvent):void {
            /* For MX containers, cast to a DisplayObject. */
            vb1.addChild(info.factory.create() as DisplayObject);

            /* For Spark containers, cast to a UIComponent. */
            vg1.addElement(info.factory.create() as IVisualElement);
        }
        ]]>
    </fx:Script>

    <!-- MX container -->
    <mx:VBox id="vb1">
        <s:Label text="Module loaded in MX VBox container:"/>
    </mx:VBox>

    <!-- Spark container -->
    <s:VGroup id="vg1">
        <s:Label text="Module loaded in Spark VGroup container:"/>    
    </s:VGroup>

</s:Application>

请注意,您仍然可以创建自己的接口,使您可以控制特定模块及其方法和属性。例如,我最近创建了一个接口,它返回对两个组件的引用(它们是 Group 的实例,但强制转换为 UIComponent):

package main.flex.interfaces
{
    import flash.events.Event;
    import flash.events.IEventDispatcher;

    import mx.core.UIComponent;

    public interface IMyModuleName extends IEventDispatcher
    {
        function get mainGroup():UIComponent;

        function get buttonRow():UIComponent;

        function init(event:Event):void;

    }
}

然后,在模块本身中,访问接口的 mainGroupbuttonRow 属性返回命名的 Group,例如

public function get mainGroup() : UIComponent {
  return someGroup;
}

...

<s:Group id="someGroup">
   <!-- content -->
</s:Group>

这些都是简化的,不使用真实的 ID,但您应该能够得到来自他们的想法。

You should create an interface for each module (or one main interface to which all your modules subscribe), defining methods that need to be called outside the modules. That way you interact with the interface, not the module itself, but the interface methods mediate between the module classes and the main application.

Using the IModuleInfo interface loaded by the ModuleManager should help you get to this. See this page for more info.

<?xml version="1.0"?>
<!-- modules/ModuleLoaderApp.mxml -->
<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"
    creationComplete="initApp()">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script>
        <![CDATA[
        import mx.events.ModuleEvent;
        import mx.modules.ModuleManager;
        import mx.modules.IModuleInfo;        
        import mx.core.IVisualElement;

        public var info:IModuleInfo;

        private function initApp():void {
            info = ModuleManager.getModule("ColumnChartModule.swf");
            info.addEventListener(ModuleEvent.READY, modEventHandler);           

            /* Load the module into memory. Calling load() makes the
               IFlexModuleFactory available. You can then get an
               instance of the class using the factory's create()
               method. */
            info.load(null, null, null, moduleFactory);
        }

        /* Add an instance of the module's class to the display list. */        
        private function modEventHandler(e:ModuleEvent):void {
            /* For MX containers, cast to a DisplayObject. */
            vb1.addChild(info.factory.create() as DisplayObject);

            /* For Spark containers, cast to a UIComponent. */
            vg1.addElement(info.factory.create() as IVisualElement);
        }
        ]]>
    </fx:Script>

    <!-- MX container -->
    <mx:VBox id="vb1">
        <s:Label text="Module loaded in MX VBox container:"/>
    </mx:VBox>

    <!-- Spark container -->
    <s:VGroup id="vg1">
        <s:Label text="Module loaded in Spark VGroup container:"/>    
    </s:VGroup>

</s:Application>

Note that you can still create your own interfaces that give you control over the specific modules and their methods and properties. For example, I recently created an interface that returns a reference to two components (which are instances of Group but casts as UIComponent):

package main.flex.interfaces
{
    import flash.events.Event;
    import flash.events.IEventDispatcher;

    import mx.core.UIComponent;

    public interface IMyModuleName extends IEventDispatcher
    {
        function get mainGroup():UIComponent;

        function get buttonRow():UIComponent;

        function init(event:Event):void;

    }
}

In the modules themselves, then, accessing the mainGroup or buttonRow properties of the interface returns the named Group, such as

public function get mainGroup() : UIComponent {
  return someGroup;
}

...

<s:Group id="someGroup">
   <!-- content -->
</s:Group>

These are simplified and don't use the real IDs, but you should be able to get the idea from them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文