为了提高容器的启动性能,和确保数据的完整性就不得不提到callLater()

一下内容来自的我对官方的翻译:

 callLater()会将它方法内部要执行的“操作”排队等候,直到下一帧的时候,才被执行,而不是当前帧执行。如果不使用callLater(),在某些情况下是会产生问题的。比如,

你的某个“操作“需要去访问某个组件的属性,但是当前帧下,这个组件的属性并没有被设置好,那么你在当前帧引用这个属性的时候,必然会产生空指针问题。

callLater()方法最普遍的使用时机是在creationComplete事件响应的时候,这样可以确保,在针对于某些组件的特殊操作的时候,其组件已经真正的创建好了!

所有的继承自UIComponent的子类都可以调用callLater()方法

官方api的解释:


Flex之旅:第二部分:容器与布局(4)--- callLater()方法的使用_xml

下面的例子延迟了doSomething()方法的调用,但是当调用doSomething()方法的时候,Flex会从数组中,将Event对象,和“Product Description” String 传入doSomething()方法里面。


callLater(doSomething, [event, "Product Description"]); 
...
private function doSomething(event:Event, title:String):void {
...
}




下面的例子,通过调用callLater()方法确保,当新的一条数据,添加到DataGrid的时候,Flex会成功地在这条新数据上设置焦点。


<?xml version="1.0"?>
<!-- layoutperformance/CallLaterAddItem.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="initData()">

<fx:Script><![CDATA[
import mx.collections.*;
private var DGArray:Array = [
{Artist:'Pavement', Album:'Charred Walls', Price:11.99},
{Artist:'Pavement', Album:'Good For You', Price:11.99}];

[Bindable]
public var initDG:ArrayCollection;
//Initialize initDG ArrayCollection variable from the Array.

public function initData():void {
initDG=new ArrayCollection(DGArray);
}

public function addNewItem():void {
var o:Object;
o = {Artist:'Pavement', Album:'Tradio', Price:11.99};
initDG.addItem(o);
callLater(focusNewRow);
}

public function focusNewRow():void {
myGrid.editedItemPosition = {
columnIndex:0,rowIndex:myGrid.dataProvider.length-1
};
}

]]></fx:Script>

<s:VGroup>
<mx:DataGrid id="myGrid" width="350" height="200" dataProvider="{initDG}" editable="true">
<mx:columns>
<fx:Array>
<mx:DataGridColumn dataField="Album" />
<mx:DataGridColumn dataField="Price" />
</fx:Array>
</mx:columns>
</mx:DataGrid>

<s:Button id="b1" label="Add New Item" click="addNewItem()"/>
</s:VGroup>

</s:Application>



另外一个是使用callLater()方法是创建递归调用。有些场景,比如动画,文本滚动,某个方法需要不停的在下一帧被重复的调用。

下面的例子,是通过HSlider的调整,去影响文本横向显示的滚动速度。


<?xml version="1.0"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark" width="400" height="200">

<fx:Script><![CDATA[

[Bindable]
public var text:String = "SLAR:95.5....TIBA:42....RTF:34.15....AST:23.42";
[Bindable]
public var speed:Number = 5;

public function initTicker():void {
theText.move( this.width+10, 0 ); // Start the text on the right side.
callLater(moveText);
}

public function moveText():void {
var xpos:Number = theText.x;
if( xpos-speed+theText.width < 0 ) {
xpos = this.width+10; // Start the text on the right side.
}
xpos -= speed;
theText.move(xpos,0);
callLater(moveText);
}

public function changeSpeed():void {
speed = speedSelector.value;
}

]]></fx:Script>

<s:Panel title="Ticker Sample" width="400" height="200">
<s:VGroup>
<mx:Canvas creationComplete="initTicker()"
horizontalScrollPolicy="off" backgroundColor="red" color="white"
width="400">
<mx:Label id="theText" text="{text}" y="0"/>
</mx:Canvas>
<mx:HBox>
<mx:Label text="Speed:"/>
<mx:HSlider minimum="1" maximum="10" value="{speed}"
id="speedSelector" snapInterval="1" tickInterval="1"
change="changeSpeed()"/>
</mx:HBox>
</s:VGroup>
</s:Panel>
</s:Application>