将子项添加到Hierarchical CollectionView

时间:2012-09-19 16:12:24

标签: actionscript-3 flex hierarchical-data

我正在尝试在ADG上实现延迟加载。而且我陷入了需要将返回的子节点添加到展开节点的程度。

目前我在做:

private function childrenloaded(data:*,item:*):void
{
    var len:int = data.length;
    for(var i=0;i<len;i++)
        (internalMainGrid.dataProvider as HierarchicalCollectionView).addChild(item, data[i]);
}

这很好,但速度很慢。 (共计21,990毫秒:919条记录) 有什么方法可以加快速度吗? - 比如直接设置孩子Ex:

var d:LazyHierarchicalData = (internalMainGrid.dataProvider as HierarchicalCollectionView).source as LazyHierarchicalData;
var ind:int = (d.source as RemoteCursorArray).getItemIndex(item);
(d.source as RemoteCursorArray)[ind].children = data;
(d.source as RemoteCursorArray).dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE));

但这并没有让人耳目一新。

欢迎任何帮助或指导更好的解决方案。提前谢谢!

2 个答案:

答案 0 :(得分:1)

我做了同样的事情。从我发现 - 使用GroupingCollection(2)和/或SummaryRow真的减慢了它。更不用说在特定节点获取新数据时重置整个树的开放关闭。

从烟雾测试性能来看,拉动/涂抹~2000行需要大约5秒钟。 现在每个节点100-200行需要大约1/2秒或更少(不计算首次调用ADG到屏幕时的初始绘制延迟)。

对我来说,我做了以下事情:

  1. 扩展HierarchicalData以根据每次从数据库中获取的摘要数据来定制子节点何时存在,并指定哪个属性包含要显示的子项(如果与子属性不同) - 我这样做这是因为我在RobotLegs MVC平台中使用的模型。
  2. 扩展AdvancedDataGridGroupItemRenderer以直观地更改公开图标(三角图形)的颜色 - 让用户知道需要提取哪些元素与已有数据的节点。将其分配给groupItemRenderer属性。
  3. 使用AdvancedDataGridEvent.ITEM_OPEN侦听器调度包含event.item属性的事件,以便命令&gt;服务&gt;响应者在UI请求的确切节点处更新模型(添加到children属性)。
  4. 将适当的CollectionChangeEvent添加到顶级集合(它的子节点是ArrayCollections - 嵌套集合不绑定)
  5. 在响应者声明完成后调用dataprovider刷新方法。
  6. 下面的伪示例:

    //Listener on Grid:
    protected function onLedgerOpenSummaryNode(event:AdvancedDataGridEvent):void 
    {
        trace('LedgerMediator.onLedgerOpenSummaryNode', event.item);
    
        if (event.item is SummaryTransaction)
        {
            refreshed = false;
            sumTrans = event.item as SummaryTransaction;
            //note - in my service responder I add the resulting db rows to the event.item
            dispatch(new AccountEvent(AccountEvent.SUMMARY_DETAIL, null, account, event.item as SummaryTransaction));
        }
    }
    
    //Dataprovider assignment to grid
    private function get dataProvider():HierarchicalCollectionView
    {
        if (!groupCollection)
        {
            groupCollection = new HierarchicalCollectionView();
            groupCollection.source = new OnDemandCollection();
        }
    
        return groupCollection;
    }
    
    //assigns the initial source to the demand collection
    private function loadTransactions():void
    {
        var odc:OnDemandCollection = OnDemandCollection(dataProvider.source);
            odc.source = account.summaryTransactions.children;
    
        transactionChangeDetection(true);
        view.callLater(deferrDataProviderUpdate);
    }
    
    //called when the service.responder dispatches it's 'complete event'.
    private function deferrDataProviderUpdate():void 
    {
        if (refreshed) return;
        dataProvider.refresh(); 
    }
    
    //add change event listener to the top-level collection
    private function transactionChangeDetection(add:Boolean):void
    {
        var collection:ArrayCollection;
        //nested collections are not binding up the object chain, so change listeners must be added/removed to/from each collection.
        for each ( var summary:SummaryTransaction in account.summaryTransactions.collection)
        {
            collection = summary.transactions.collection;
            add ? collection.addEventListener(CollectionEvent.COLLECTION_CHANGE, onTransactionUpdate)
                : collection.removeEventListener(CollectionEvent.COLLECTION_CHANGE, onTransactionUpdate);
        }
    }
    
    //block the refresh method - only interested in add,delete,update
    protected function onTransactionUpdate(event:CollectionEvent):void 
    {
        if (event.kind == CollectionEventKind.REFRESH) return;
        view.callLater(deferrDataProviderUpdate);
    }
    
    
    public class ExtAdvancedDataGridGroupItemRenderer extends AdvancedDataGridGroupItemRenderer 
    {
        private var defaultColor:ColorTransform;
    
        public function ExtAdvancedDataGridGroupItemRenderer() 
        {
            super();
        }
    
        override protected function commitProperties():void 
        {
            super.commitProperties();
            if (disclosureIcon) defaultColor = disclosureIcon.transform.colorTransform;
        }
    
        override protected function updateDisplayList(w:Number, h:Number):void 
        {
            super.updateDisplayList(w, h);
    
            if (!listData || !data) return;
    
            var adgld:AdvancedDataGridListData = AdvancedDataGridListData(listData);
            var adg:AdvancedDataGrid = adgld.owner as AdvancedDataGrid;
            var hcv:HierarchicalCollectionView = adg.dataProvider as HierarchicalCollectionView;
            var source:IHierarchicalData = hcv.source;
    
            var useDefaultColor:Boolean;
            var visible:Boolean;
            if (!data) visible = false;
            else if (!source.canHaveChildren(data)) visible = false;
            else if (source.hasChildren(data)) 
            {
                useDefaultColor = true;
                visible = true;
            }
            else
            {
                visible = true;
    
                var ct:ColorTransform = new ColorTransform();
                    ct.color = 0xBCB383;
                disclosureIcon.transform.colorTransform = ct;
            }
    
            if (useDefaultColor) disclosureIcon.transform.colorTransform = defaultColor;
            disclosureIcon.visible = visible;
        }
    }
    
    public class OnDemandCollection extends HierarchicalData
    {
    
        public function OnDemandCollection() 
        {
            super();
        }
    
    
        override public function getChildren(node:Object):Object 
        {
            if (node is SummaryGrouping) return SummaryGrouping(node).children;
            else if (node is SummaryTransaction) return SummaryTransaction(node).children;
            else if (node is Transaction) return Transaction(node).children;
    
            return {};
        }
    
        override public function canHaveChildren(node:Object):Boolean 
        {
            if (node is SummaryGrouping)
            {
                return true;
            }
            else if (node is SummaryTransaction)
            {
                var sumTran:SummaryTransaction = SummaryTransaction(node);
                return sumTran.numTransactions > 0;
            }
            else if (node is Transaction)
            {
                var tran:Transaction = Transaction(node);
                return tran.isSplit;
            }
            else if (node is Split) return false;
            else if (node.hasOwnProperty('children'))
            {
                var list:IList = node['children'] as IList;
                return list.length > 0;
            }
            else return false;
        }
    }
    

答案 1 :(得分:0)

您应该从collection_change发送internalMainGrid.dataProvider个事件来触发视图中的更改或调用refresh()方法(它属于ICollectionView,由{HierarchicalCollectionView实现1}}作为IHierarchicalCollectionView)的实现者,在同一个dataProvider上。