只是想知道是否有人遇到過這個問題,並且有很好的解決方法。Flex 3 - 顯示事件處理程序失效破壞生命週期
下面是如何重現:
創建標籤導航器(或viewstack,等等),並添加一對夫婦的標籤。
在您的選項卡上添加一個顯示事件處理程序。在事件處理程序內部,在選項卡的其中一個子項中調用invalidateProperties()和invalidateDisplayList()。在孩子的commitProperties()和updateDisplayList()上放置一個斷點。您會注意到updateDisplayList()在commitProperties()之前被調用,導致不正確的行爲。
從show handler中設置DataGrid的dataprovider時,我發現這個問題。設置dataProvider將導致網格使屬性和displayList無效,updateDisplayList()將首先被調用,然後commitProperties()將導致網格不更新行。
看來問題的根源在於顯示事件從LayoutManagers validateDisplayList()循環內調度,因此在show handler中使子對象失效導致其updateDisplayList()立即被調用。
我知道我可以在show handler或其他一些hacky解決方案中使用callLater(),但我更願意修復問題的根源,因爲我不想在每次有人使用時發現/修復此問題展會事件和不好的事情發生。
我正在考慮更改調度show事件和使用dispatchEvent()上的callLater()的UIComponent.setVisible(),因此show事件將不會在中間驗證週期中調度,除非任何人有更好的主意。
<mx:Script>
<![CDATA[
import mx.controls.Label;
private var tabLabel:Label;
private function onCreationComplete():void
{
var ifactory:IFactory = TestLabel;
tabLabel = Label(ifactory.newInstance());
tab1.addChild(tabLabel);
}
private function onTab1Show():void
{
tabLabel.invalidateProperties();
tabLabel.invalidateDisplayList();
}
]]>
</mx:Script>
<mx:Component id="TestLabel">
<mx:Label text="Test">
<mx:Script>
<![CDATA[
override protected function commitProperties():void
{
super.commitProperties();
}
override protected function updateDisplayList(w:Number, h:Number):void
{
super.updateDisplayList(w, h);
}
]]>
</mx:Script>
</mx:Label>
</mx:Component>
<mx:TabNavigator height="200" width="200" creationComplete="onCreationComplete()">
<mx:Canvas id="tab1" height="100%" width="100%" label="Tab 1" show="onTab1Show()" />
<mx:Canvas height="100%" width="100%" label="Tab 2" />
</mx:TabNavigator>
是的,它是不尋常的,但它確實有效。此外,考慮到這個錯誤會影響任何支持show事件的組件的孩子,這是一個巨大的問題,我不知道有什麼方法可以在不改變SDK的情況下在全局範圍內修復它。 –
向我們展示一些代碼來重現,我會看看。 – JeffryHouser
你是否想讓我把它的斷點給你呢?您必須分解commitProperties()和updateDisplayList()才能看到問題。我不認爲這種情況下的代碼是必要的,因爲這個問題很容易重現,並且可以使用任何支持show事件的組件來完成。只需添加一個子節點和一個顯示處理程序,即可使顯示處理程序中的子節點失效,並觀察它在子節點上調用commitProperties和updateDisplayList的順序。 –