Flex之旅:第二部分:容器与布局(7)---使用IdeferredInstance 创建模板,实现组件的延迟加载

来源:互联网 发布:黑人歧视黄种人知乎 编辑:程序博客网 时间:2024/05/21 22:45

我们都会通过FlashBuilder创建一个组件(component),




一般情况下,当主程序(Application)引用到此组件的时候,该组件就会被自动的创建出来。

如果主程序(Application)引用了太多的组件,那么主程序在创建的时候,就会很耗时。

  • 为了提高主程序的启动效率
  • 或者业务逻辑希望,某个组件不要马上被初始化
  • 那么就需要让组件延迟加载(实例化)。
此时就需要使用 IdeferredInstance。


如何使用IdeferredInstance:
  • IdeferredInstance是一个接口(mx.core.IDeferredInstance)
  • UIComponents 都实现IdeferredInstance 接口
  • 那么UIComponents 都可以通过调用getInstance()方法,去实例化(在你想要实例化的时候):
    • 一个component(组件),内部包含的所有子组件,都可以根据自己的需要,事先定义成IDeferredInstance的对象(public var header:IDeferredInstance;)
    • 或者将子组件集,放在数组里面,数组里面存储的都是IDeferredInstance的对象。
    • 最后,在你想要实例化的时候,通过调用getInstance()方法,生成对象,再添加到可视化组件上,将他们都显示出来。


先看具体代码:


自定义组件(component)DeferredVBox.mxml:

<?xml version="1.0" encoding="utf-8"?><mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" borderStyle="solid" ><fx:Script><![CDATA[import mx.containers.HBox;import mx.containers.ViewStack;import mx.core.UIComponent;// 定义IDeferredInstance的属性,至于它具体是哪个可视化组件,和该组件如何初始化, 在这里,我们可以先不去考虑public var header:IDeferredInstance;// 定义三个数组,声明数组里面所存储的对象都是 mx.core.IDeferredInstance的实例// 在这里,至于这些数组是如何初始化, 和数组里面具体存储的是哪些可视化组件,我们可以先不去考虑[ArrayElementType("mx.core.IDeferredInstance")]public var leftDataRow:Array;[ArrayElementType("mx.core.IDeferredInstance")]public var centerDataRow:Array;[ArrayElementType("mx.core.IDeferredInstance")]public var rightDataRow:Array;// 这种定义的方式,虽然是初始化对象是异步的,但是它得表述,规定了,此对象必须是HBox类的对象。public var layoutHBox:HBox;public var layoutWidth:int = 0;/** * 暴露一个公共方法,让程序可以随时根据逻辑需要,延迟初始化子组件 *  * */public function createDeferredComponents():void {addChild(UIComponent(header.getInstance()));layoutHBox = new HBox();if(layoutWidth != 0){layoutHBox.setStyle("horizontalGap", layoutWidth);}if(leftDataRow.length > 0){var leftVBox:VBox = new VBox();layoutHBox.addChild(leftVBox);for (var i:int = 0; i < leftDataRow.length; i++){leftVBox.addChild(UIComponent(leftDataRow[i].getInstance()));}}if(centerDataRow.length > 0){var centerVBox:VBox = new VBox();layoutHBox.addChild(centerVBox);for (var i:int = 0; i < centerDataRow.length;i++){centerVBox.addChild(UIComponent(centerDataRow[i].getInstance()));}}if(rightDataRow.length > 0){var rightVBox:VBox = new VBox();layoutHBox.addChild(rightVBox);for (var i:int = 0; i < rightDataRow.length;i++){rightVBox.addChild(UIComponent(rightDataRow[i].getInstance()));}} // Add the HBox container to the VBox container.addChild(layoutHBox);}]]></fx:Script></mx:VBox>


主程序(application): DeferredTest.mxml


<?xml version="1.0" encoding="utf-8"?><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" minWidth="955" minHeight="600" xmlns:local="*"><fx:Declarations><!-- Place non-visual elements (e.g., services, value objects) here --></fx:Declarations><fx:Script><![CDATA[/** * 比如,根据业务逻辑需要,只有在Button点击的时候,才开始创建DeferredVBox里面的子组件。 * 注意,是DeferredVBox里面的子组件是延迟初始化的!而不是DeferredVBox本身, * 在这里DeferredVBox,我故意给他一个黑色边框, * 可见,在主程序初始化的时候,DeferredVBox本身,已经渲染好了, * 当点击Button,才开始创建DeferredVBox里面的子组件得内容!!!! * */private function createDeferredInstance():void{this.deferredInstance.createDeferredComponents();}]]></fx:Script><mx:VBox><mx:Button click="createDeferredInstance()"   label="make components"/><local:DeferredVBox layoutWidth="30"id="deferredInstance"><!-- 通过标签赋值, 此时告诉DeferredVBox.header属性,它就是Label可视化组件(<span style="font-family: Arial, Helvetica, sans-serif;">Label </span>extends UIComponent) --><!-- 此时,仅仅是完成描述定义的过程, 还没有实例化对象--><local:header><mx:Label text="This will be the header of my templated  component"/></local:header><!-- 通过标签赋值, 此时leftDataRow数组被初始化:告诉数组里面存储的是3个Label --><!-- 此时,仅仅是完成描述定义的过程, 还没有实例化对象--><local:leftDataRow><fx:Array><mx:Label text="data"/><mx:Label text="data"/><mx:Label text="data"/></fx:Array></local:leftDataRow><!-- 通过标签赋值, 此时centerDataRow数组被初始化: 告诉数组里面存储的是一个Label和一个Button --><!-- 此时,仅仅是完成描述定义的过程, 还没有实例化对象--><local:centerDataRow><fx:Array><mx:Button label="press me"/><mx:Label text="data"/></fx:Array></local:centerDataRow><!-- 通过标签赋值, 此时rightDataRow数组被初始化: 告诉数组里面存储的是一个Label,一个CheckBox和一个Button --><!-- 此时,仅仅是完成描述定义的过程, 还没有实例化对象--><local:rightDataRow><fx:Array><mx:CheckBox label="click"/><mx:Button label="press me"/><mx:Label text="data"/></fx:Array></local:rightDataRow></local:DeferredVBox></mx:VBox></s:Application>


运行截图:






0 0