【问题标题】:How to introspect a Flex component before adding it to display如何在将 Flex 组件添加到显示之前对其进行自省
【发布时间】:2010-11-22 09:53:23
【问题描述】:

假设你有一个 MyView.mxml 文件,它基本上是一个面板 几个孩子(Form、FormItems、Buttons...)。

是否可以遍历 MyView 并获取有关的所有信息 它的子项(类型、id ...)在显示之前。

如果我有这个功能,在我的 Main.mxml 中

    public function iterateOverChildren(comp:Container):void {
        // Get the number of descriptors.
        trace("Running iterateOverChildren for " + comp.id);
        if (comp != null)
        {
        var n:int = comp.childDescriptors.length;
        for (var i:int = 0; i < n; i++) {
            var c:ComponentDescriptor = comp.childDescriptors[i];
            var d:Object = c.properties;

            // Log ids and types of objects in the Array.
            trace(c.id + " is of type " + c.type);

            // Log the properties added in the MXML tag of the object.
            for (var p:String in d) {
                trace("Property: " + p + " : " + d[p]);
            }
        }
        }
    }

为什么这个调用不起作用?

var myV = MyView(); iterateOverChildren(myV);

仅当我添加如下语句时它才有效 addChild(myV); 在 iterateOverChildren 调用之前。 (但这不是我想要的,我想要 迭代描述而不将其添加到显示中)。

当我读到这篇文章时 http://livedocs.adobe.com/flex/3/html/help.html?content=layoutperformance_06.html

我认为“childDescriptors”方法是独立于生命周期的,它可以让我在不添加到显示的情况下内省组件。我错过了什么 ?如何在显示之前自省组件。

【问题讨论】:

  • 您究竟为什么要遍历 MyView 的所有子项?根据您要查找的信息,有多种方法。
  • 我在每个用户角色的后端都有每个项目(子项)的元数据。我曾经带来所有的元数据,但现在应用程序变得越来越大,并且只想从后端降低相关的元数据。在实例化之前,我想写一些动态的东西来从 MyView 中找到所有这些“id”(这是我的元数据的关键)。我知道 getChildren 结果取决于creationPolicy,所以当我读到childDescriptors 时,它看起来就像我正在寻找的东西。

标签: apache-flex components


【解决方案1】:

Flex 中有多种组件实例化方式。

如果您在 ActionScript 中使用构造函数,您将获得一个裸机对象,其中除了对象本身的构造之外什么都已完成。特别是,这个新对象还没有实例化它的子视图,这就是为什么当你查看getChildren() 的结果时什么都看不到的原因。

如果您在 MXML 中写下您的组件,MXML 编译器会创建 ComponentDescriptors 而不是“真实”对象。这些包含您为 MXML 中的对象指定的所有信息(属性、绑定、事件处理程序等),运行时使用它们在适当的时间创建真实对象。 “适当的时间”通常是指“将对象添加到显示列表时”。这就是为什么您只在调用 addChild() 之后才能看到孩子(从技术上讲,不是在调用 addChild() 之后,而是在您新实例化的对象已调度它的 creationComplete 事件之后)。

【讨论】:

  • 谢谢西蒙。我想我仍然不能 100% 理解 childDescriptors 的使用超过 getChildren()。 “所有容器都有一个 childDescriptors 属性。根据 creationPolicy 属性的值,Flex 会立即开始实例化容器内的控件或推迟它们的实例化。如果实例化被推迟,您可以使用此 Array 的属性来访问每个容器的 ComponentDescriptor组件并在指定时间创建该对象。”您对上述说明的解释是不是立即可用的描述符。
  • 描述符立即可用,但仅适用于在 MXML 代码中创建的对象。如果您通过调用 var myV = MyView(); 中的构造函数在 ActionScript 中实例化一个对象,您将获得一个没有 childDescriptors 的真实对象。
  • 知道了,谢谢。如果我这样做 var myV = MyView(); myV.initialize(); iterateOverChildren(myV);我会得到信息。我怎样才能使这个递归?在我的 iterateIVerChildren 代码中,var c 是一个 ComponentDescriptor。我能找到 c 的孩子吗?
  • UIComponent.initialize() 已经递归工作。调用它之后,你应该可以通过 getChildren() 访问 myV 的孩子了。
  • 此外,过去当文档不清楚时,阅读 Flex 源代码对我有帮助。它的可读性很好。
猜你喜欢
  • 2020-07-03
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多