将子项添加到 HierarchicalCollectionView [英] Add children to HierarchicalCollectionView

查看:23
本文介绍了将子项添加到 HierarchicalCollectionView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 ADG 上实现延迟加载.我被困在需要将返回的子节点添加到扩展节点的地方.

I'm trying to implement lazy loading on ADG. and I'm stuck in the point where I need to add the returned children to the expanded node.

目前我在做:

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:

This works fine, but it is slow. (21,990 ms for total: 919 records) is there some way I can speed this up? - like setting children directly 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));

但这并没有刷新视图.

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

Any help or direction towards a better solution is welcome. Thanks in advance!

推荐答案

我也做过同样的事情.根据我的发现 - 使用 GroupingCollection(2) 和/或 SummaryRow 确实会减慢它的速度.更不用说在特定节点获取新数据时整个树的开闭都会重置.

I've done the same thing. From what I've found - using a GroupingCollection(2) and/or SummaryRow's really slows it down. Not to mention the entire tree open-close is reset when fetching new data at a particular node.

从烟雾测试性能来看,拉/涂约 2000 行大约需要 5 秒.现在每个节点的 100-200 行大约需要 1/2 秒或更短的时间(不包括第一次调用 ADG 到屏幕时的初始绘制延迟).

From smoke-test performance, it would take approx 5sec to pull/paint ~2000 rows. It now takes about 1/2sec or less for 100-200 rows at each node (not counting the initial paint lag when first calling the ADG to the screen).

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

For me, I have done the following:

  1. 扩展 HierarchicalData 以根据我每次从数据库获取的摘要数据自定义子节点何时存在,并指定哪个属性包含要显示的子节点(如果与 children 属性不同)- 我这样做是因为我在 RobotLegs MVC 平台中使用了模型.
  2. 扩展 AdvancedDataGridGroupItemRenderer 以在视觉上更改显示图标(三角形图形)的颜色 - 让用户知道需要获取哪些元素与已有数据的节点.将此分配给 groupItemRenderer 属性.
  3. 使用 AdvancedDataGridEvent.ITEM_OPEN 侦听器调度包含 event.item 属性的事件,以便命令 > 服务 > 响应程序在 UI 请求的确切节点上更新模型(添加到儿童财产).
  4. 将适当的 CollectionChangeEvent 添加到顶级集合(它的子项是 ArrayCollections - 嵌套集合没有绑定)
  5. 在响应者声明完成后调用 dataprovider refresh 方法.
  1. Extend HierarchicalData to customize when children nodes will exist based on summary data I fetch every time from the db, and to specify which property contains the children to be displayed (if different from the children property) - I do this because of the Models I use in a RobotLegs MVC platform.
  2. Extend the AdvancedDataGridGroupItemRenderer to visually change the color of the disclosure icon (triangle graphic) - to let the user know which elements need to be fetched vs. a node that already has data. Assign this to the groupItemRenderer property.
  3. Use AdvancedDataGridEvent.ITEM_OPEN listener to dispatch an event which contains the event.item property so that a command > service > responder updates the the model at the exact node requested by the UI (adding to the children property).
  4. Add the appropriate CollectionChangeEvent to the top-level collection (it's children are ArrayCollections - nested collections are not binding)
  5. Call the dataprovider refresh method after the responder has declared it's complete.

以下伪示例:

//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;
    }
}

这篇关于将子项添加到 HierarchicalCollectionView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆