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

我们都会通过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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值