如果没有在Flex中进行硬编码,元素应该如何在树中进一步引用元素?

时间:2010-07-09 16:02:02

标签: flex actionscript-3 actionscript flex4

我有一个用AS3编写的自定义Flex容器组件,名为StatisticsContainer。在应用程序中使用时,它包含各种称为StatisticsBoxes的自定义Label组件。所以可能有一个StatisticsContainer包含3个StatisticsBox:“averageAge”,“divorceRate”和“infantMortalityRate”。

StatisticsContainer需要能够引用和操作所有StatisticsBox。但是我不想将引用硬编码到StatisticsContainer中,因为将有各种不同的StatisticsContainer实例,其中包含不同的StatisticsBox。

那么如何动态地为StatisticsContainer提供它包含的所有StatisticsBox的ArrayCollection?

到目前为止,我在statisticsContainer的creationComplete中开始使用这样的函数:

for (var i:int = 0; i < numElements; i++) {
  if (getElementAt(i) is StatisticsBox) {
    statisticsBoxes.addItem(getElementAt(i));
  }
}

仅当StatisticsBox是直接子子项时才有效。无论如何,它感觉有点hacky。

然后我尝试在StatisticsContainer中侦听CreationComplete事件。但是,这些不是从StatisticsBox到达的,因为它们不会冒泡。

最后,我创建了自己的事件,冒泡,我在StatisticsBox中的creationComplete上触发它,并在StatisticsContainer中监听它。这有效,但这真的是最好的方法吗?

2 个答案:

答案 0 :(得分:1)

创建时,您可以让每个StatisticsBox注册自己的StatisticsBoxContainer

<强> StatisticsBoxContainer.mxml

<?xml version="1.0"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">
    <mx:Script><![CDATA[
        import mx.collections.ArrayCollection;

        public var statisticsBoxes:ArrayCollection = new ArrayCollection();

]]></mx:Script>

    <local:StatisticsBox id="stats1" />
    <local:StatisticsBox id="stats2" />
    <local:StatisticsBox id="stats3" />

</mx:Canvas>

<强> StatisticsBox.mxml

<?xml version="1.0"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onCreationComplete()">
    <mx:Script><![CDATA[

        private function onCreationComplete():void {
            StatisticsBoxContainer(parentDocument).statisticsBoxes.addItem(this);
        }

]]></mx:Script>       
</mx:Canvas>

我不确定这是否比通过孩子循环更多或更少。你现在如何循环的问题是你需要通过子孙,孙子等递归循环。

答案 1 :(得分:0)

我在几个不同的项目中遇到了确切的问题。为了速度,我通过快速循环遍历所有孩子来解决它,正如你所做的那样,在创作完成时感觉就像“肮脏”和“hacky”一样,但它完成了工作。

ActionScript并不像其他语言那样成熟,因此许多解决方案需要快速入侵,因为正确地执行它需要编写整个框架,这是不切实际的。

我还使用Application.application对象解决了这个问题,这是获取全局引用的一个很酷的小技巧。当我在我的应用程序中需要单例实例时,我会使用它。再次,hacky,但优雅简单。

将其应用于您的情况,而不是触发必须在代码中冒泡的事件,无论何时创建“子框”(并且您的自定义事件曾经被触发),您都可以按照以下方式执行操作):

Application.application.StatisticList.addItem(this);

我在这种情况下使用的另一个很酷的技巧是字典而不是ArrayCollections。它们使我能够在需要时进行“即时查找”,同时在必要时仍允许迭代。您可以迭代键和字典的值。代码变成了:

Application.application.StatisticList[this.id] = this;

现在,您可以通过以下三种方式访问​​统计信息:

  1. 立即通过直接身份
  2. 以“顺序”,迭代所有ID
  3. 以“顺序”,迭代所有StatisticBox对象(与ArrayCollection相同的功能)
  4. 我希望其中一些有所帮助,

    - gMale