Flex主题教程系列4--Flex组件生命周期之生活周期

来源:互联网 发布:无主之地2mac汉化 编辑:程序博客网 时间:2024/06/03 13:52

上一节我们讲了Flex生命周期的 第一个周期出生时期这节我们介绍下Flex生命周期的第二个周期--生活周期。

当Flex经过出生时期的时候就进入到了生活周期。进入到生活周期就代表Flex组件可以被看见,被操作,甚至被删除。并且作为一个成熟的个体,组件可以和外界进行交互,对更新请求进行响应,Flex主要是通过invalidation-validation模式来响应请求的。

验证--提交模式(Invalidation - validation pattern)

Flex的生命周期是建立在帧模型之上的,所以同样遵循先执行脚本后渲染的规则。为了达到浏览的视觉体验,我们通常能够期望尽量减少代码执行的消耗,而给画面渲染留下充足的时间,为了实现这一点Flex实现了 Invalidation-validation 模式,来实现资源的有效利用

如图描述了Invalidation-validation模式


验证提交模式提供了一个低耦合的处理过程将数据的改变(旧数据的失效)和数据的处理(对新数据的重新使用)这样的好处是:

1.只有在屏幕刷新需要时进行数据的相应操作和计算

2.避免了不必要的重复渲染

例如下面代码

var button:Button = new Button();button.width = 20;button.width = 20;//此段代码永远不会被执行

第三行代码永远不会被执行,这样就避免了画面的重复渲染

那Flex框架是如何实现这个模式的呢?我们看下Button的setWidth()方法

 override public function set width(value:Number):void    {        if (explicitWidth != value)        {            explicitWidth = value;            // We invalidate size because locking in width            // may change the measured height in flow-based components.            invalidateSize();        }        if (_width != value)        {            invalidateProperties();            invalidateDisplayList();            invalidateParentSizeAndDisplayList();            _width = value;                        // The width is needed for the _layoutFeatures' mirror transform.            if (_layoutFeatures)            {                _layoutFeatures.layoutWidth = _width;                invalidateTransform();            }                        if (hasEventListener("widthChanged"))                dispatchEvent(new Event("widthChanged"));        }    }

从上述代码中我们会看到此方法首先会判断值是否改变,从而避免重复渲染带来的消耗然后调用invalidateSize()方法,invalidateSize()是校验方法之一,他用来校验与组件尺寸大小相关的属性。此方法调用后Flex组件引擎LayoutManager 会首先检查该组件的属性更新请求是否调用invalidateSize()方法,如果调用过,说明此类型的更改请求已经记录在案,无需赘述。如果没有,则会将此次请求记录到 LayoutManager 校验队列上进行等待。那么对 width 属性值的更新什么时候生效呢? LayoutManager 会在监听到下一次 RENDER 事件派发的时候,将组件推送到提交阶段。在提交阶段,LayoutManager 得到更新请求队列,调用 commitProperties()方法使得属性 width 的最新值(假设记录在了 _width 私有变量上)得以生效。Flex 就是通过这种属性值延迟生效的方法来保证每次用于渲染画面的请求都是最新的,从而避免了不必要的资源浪费。

验证阶段

验证阶段是组件在生活要经历的第一步,具体地说是响应更新请求的第一步。作为 invalidation-validation 循环的一份子他会在组件的生命周期中多次执行。Flex 组件基类 UIcomponent 提供了三种验证方法:invalidateProperties()、invalidateSize()和 invalidateDisplayList() 来分别响应组件对值相关,布局相关和显示相关属性的更新请求。

组件会通过两种方式进入到验证阶段:

第一种方式是在初始化阶段,通过父节点调用 childrenCreated() 方法,组件进入第一次 Invalidation – validation 循环。这一次,三种验证方法都会被自动调用以确保组件初始化成功。这类调用在组件的生命周期内只会经历一次。

第二种方式是响应更新请求。组件的任何一方面特性发生更新请求后,都会进入到验证阶段。而此时,用户需要根据特性的不同类别来自行决定调用哪种验证方法。还是以清单 9 为例,通过调用 invalidateProperties()方法,确保了在接下来的提交阶段,更新会对值计算生效。

在这个时期,我们通常不去做太多的事情,因为此时只是验证阶段,更新并不生效。我们所要做的只是记录此次更新,并且等待进入提交阶段。

提交阶段

通过以上的介绍,我们已经很清楚组件更新会在提交阶段实际生效。和验证阶段的随时更新随时校验不同,Flex 框架为提交阶段设计了线性执行的顺序,将三个提交方法分为了三个阶段。顺序调用三个提交方法:commitProperties(),measure()和 updateDisplayList()。这样做的目的和每个方法的功能有关。commitProperties()方法主要负责属性值的计算和生效,因此首先执行,因为这些自己算过的值可能用于布局,也可能用于显示。这里也可以用来移除不需要的子节点,但是您需要通过标志位来判断子节点是否存在。

measure()方法用于根据组件的内容大小计算组件尺寸。由于尺寸的计算是自下而上的,所组件子元素的大小改变都会隐试的触发此方法。

UpdatedisplayList() 方法用来更新显示列表(Display List)的布局以及渲染。组件的布局是一个自上而下的过程,所以在这个方法里您需要对不仅仅是组件设置布局属性,而且也要对子元素进行相应的调整。这里也是使用 Flash 绘图 API 的好地方。

这里,我们所要做的就是覆盖(override)这几个方法,在正确的时间、正确的地方做正确的事。

提示:响应组件更新请求时,调用三种验证方(invalidateProperties()、invalidateSize()、invalidateDisplayList()),而不要显试调用提交方法(commitProperties(),measure()和 updateDisplayList())。Flex 框架会在最合适的时候自行调用提交方法。

交互阶段

交互严格地说组件生命周期中的某种行为,他是促使组件更新,推动验证 - 提交循环的动力。

Flex 使用事件驱动的交互模式,来实现一种完全松耦合的体系结构。简单地说,任何组件如果想要告诉外界当前发生了什么事或者即将发什么事的话,他可以派发一个事件,那么在该类事件可及范围内的任何组件都可以通过注册该事件的监听器的方式来对此类事件进行相应。关于 Flex 在事件机制处理方面信息的由于超出了本文的范围,这里不再多讲,感兴趣的读者可以关注后续教程《探索 Flex 的事件机制》,或者阅读资料部分的相应文档。

一般来说,组件的交互行为有以下几种:

用户同组件的交互,比如说:输入数据,缩放大小等等。

通过派发和响应事件。

应用(Application)或者父节点(parent)与组件的交互。比如说 ItemRenderer 实例和宿主对象之间的 data 传递


本节内容结束下节将介绍最后一个时期销毁时期