【转】深入Flex4——了解Element和Child的异同

当我了解到Flex4那些对我诸多裨益的新特性后,我便决定转而使用它。刚开始的时候,我试图利用在Flex前作中的认识和既有经验来快速进入状态。但很快我便发现有时即使面对一些显而易见的问题我也不得不求助于API文档或者运行一些示例程序来弄清这种问题的来龙去脉。根据以往经验,Flex3的Halo在处理显示列表的时候隐藏了大量的实现细节和不良设计。然而一旦你开始使用新的Spark架构后,你就得以近距离的面对这些实现细节—Halo究竟在私底下干了什么,而且你会体会到为什么说Spark对于显示列表的处理更为“直白”。

“elements”是一个关键性的问题。elements是何物?它同child是否是一回事?刚开始的时候我曾武断的认为elements不过是children的另一种说法。通过反复梳理组件中所有的elements和children,我发觉在新的容器类(也包括一些经过改良的传统容器)某些似乎是理所当然应该具备的方法消失了。如果没有getElements(),我该如何获取elements的数目呢?我能否把getChildren()的返回结果作为IVisualElement来对待。这令我十分纠结。

困扰的我于是开始认真阅读学习API文档,Flex的源码以及相关的博客文章。我也曾尝试解读一些博主发布的关于Flex4新特性的幻灯片。然而事实证明脱离讲解而孤立的看幻灯片作用相当有限。

最后,我拼凑了一些言简意赅的示例。这些示例将带领我了解有关elements的全新知识,告诉我那些在新的Spark容器背后发生的故事。

言归正传,首先从问题开始。

问题一,“应该如何获得Spark容器的全部elements?”

我曾想当然的认为是通过一个类似Flex3中的getChildren()的方法。然而实际上我们需要通过两个Property来达到这个目的:numElements & numChildren 。可以通过对numElements计数的循环语句配合getElementAt()来实现遍历容器elements或特定访问。这种方式还比较直观。

问题二,“element和child的区别何在?”,让我们来看看两者的差异。

语义上,element简单的说就是实现了IVisualElement接口的任意型别。child是指扩展了DisplayObject类的任意型别。判断某个组件是element还是child亦或两者都是的关键在于以下几点。UIComponent(所有Flex组件的基类:译者注)是由DisplayObject扩展而来,故所有UIComponent都是DisplayObject,也就是说UIComponent都是children。UIComponent同时也实现了IVisualElement接口,因而所有的UIComponent也可以被作为elements看待。但这并不是说所有的DisplayObjects(文中所言的DisplayObject一般指扩展于DisplayObject的子类,译者注)都是elements。容器中的DisplayObject对象是该无疑是容器的child。而只有当此DisplayObject对象同时也实现了IVisualElement接口时它才是容器的element。那么对容器而言,DisplayObject什么情况下是child,什么情况下又是element?通过示例来认识这个问题。

在首个示例中,我们使用了传统的Halo容器(这里我们使用的Panel)。Panel扩展与DisplayObject类,所以它可以使用addChild()方法。进一步而言,Panel也是Container类的子类(mx.core.Container实现了IVisualElementContainer接口),它具有addElement()方法。Container类的IVisualElementContainer接口实现只是基于显示列表API的门面,所以理论上它和同样实现了IVisualElementContainer接口的新式Spark容器具有相同的方法集合。

请使用下面的链接升级 Flash Player 到最新版本:

安装最新的Flash Player插件

源文件

通过以上阅读,也许起不到拨云见日的效果。但可以让你明白厘清以下七个类/接口的继承结构和相互关系是十分有必要的:

  1. DisplayObject
  2. UIComponent
  3. Container
  4. IVisualElement
  5. IGraphicElement
  6. IVisualElementContainer
  7. ISharedDisplayObject

一旦你掌握它们之间的关系,你就能明白elements和children的不同。可以肯定的是我在某些问题的认识和阐述上存在很多谬误之处。如果你发现了这样的问题望不吝赐教,在评论处写下您的正确观点吧。

访问下面的链接可以获得关于本文探讨及其相关的主题的更多内容。

Gumbo DOM Tree API(关于本话题的详实细节)

关于了解组件的owner和parent之间差异的极好的示例