2015-11-02 46 views
0

我想要以這樣的方式打開Flex mx樹的所有節點,使UI始終處於響應狀態。通常情況下,當沒有節點時,這段代碼工作得很好。當超過30000個節點時,Flex樹緩慢展開/延遲加載

public function expandAllNodes():void { 
    for (var i:int = 0; i < this.dataProvider.length; i++) { 
    expandChildrenOf(this.dataProvider.getItemAt(i), true); 
    } 
} 

也許我需要使用callLater而不是直接調用該函數

public function expandAllNodes():void { 
    for (var i:int = 0; i < this.dataProvider.length; i++) { 
    calllater(expandChildrenOf,[this.dataProvider.getItemAt(i), true]); 
    } 
} 

但這不是工作要麼。

回答

0

在這種情況下使用callLater將無濟於事。來自documentation,

callLater方法將爲下一個屏幕刷新而不是當前更新排隊要執行的操作。

在循環使用使用callLater只會推所有的expandChildrenOf()調用到下一個屏幕刷新 - 仍然把太多的工作進入一個更新週期。

相反,你可以展開你的循環在幾個幀和極限工作每幀進行:

private var processingLimit:int = 10; //experiment to get a reasonable value for this 
private var totalNodes:int = 0; 
private var nodesProcessed:int = 0; 

public function expandAllNodes():void { 
    this.totalNodes = this.dataProvider.length; 
    this.addEventListener(Event.ENTER_FRAME, expandNextNode); 
} 

private function expandNextNode(e:Event):void { 
    var numToProcess = Math.min(processingLimit + nodesProcessed, totalNodes); 
    for (var i:int = nodesProcessed; i < numToProcess; i++) { 
     nodesProcessed++; 
     expandChildrenOf(this.dataProvider.getItemAt(i), true); 
    } 

    if (numToProcess == totalNodes) { 
     this.removeEventListener(Event.ENTER_FRAME, expandNextNode); 
    } 
} 

注:確保expandChildrenOf不會遞歸地打開子女的孩子 - 如果是這樣的話,那麼您仍然可以通過一次調用expandChildrenOf(1);來擴展整棵樹!

+0

感謝布賴恩,Event.ENTER_FRAME工作正常。 –

+0

它應該是** Math.min **而不是** Math.max **嗎? – gbdcool

+0

@gbdcool好的。我會解決這個問題。 – Brian

0

這是我如何解決這個問題

private const PROCESSING_LIMIT:int = 25; 
public var _expandNodesStack:Vector.<Object>; 
private function expandNextNode(e:Event):void { 
    for (var i:int = 0; i < PROCESSING_LIMIT; i++) { 
    var item:* = _expandNodesStack.pop(); 
    if (item) 
     expandItem(item, true); 
    else 
     break; 
    } 
    if (_expandNodesStack.length == 0) { 
    this.removeEventListener(Event.ENTER_FRAME, expandNextNode); 
    } 
} 



public function expandAllNodes():void { 
    if(this.dataProvider == null || this.dataProvider.length <= 0) return; 
    if (_expandNodesStack != null && _expandNodesStack.length > 0) { 
    //already expanding so abort this operation 
    return; 
    } 
    if (_expandNodesStack == null) _expandNodesStack = new <Object>[]; 
    iterateAndPushToStack(this.dataProvider.getItemAt(0)); 
    _expandNodesStack.reverse(); 

    this.addEventListener(Event.ENTER_FRAME, expandNextNode); 
} 

private function iterateAndPushToStack(item:Object):void { 
    if (iterator == null) 
    return; 

    // if it is not a branch item there's nothing to do 
    if (item != null && item.children is ArrayCollection && item.children.length > 0) { 
    _expandNodesStack.push(item); 
    var childItems:ArrayCollection; 
    childItems = item.children; 
    if (childItems) { 
     for each (var object:Object in childItems) { 
     iterateAndPushToStack(object); 
     } 
    } 
    } 
}