如何使用HierarchicalData停止AdvancedDataGrid,将具有多个父项的子元素移动到不同的级别?

时间:2012-04-17 16:56:42

标签: actionscript-3 flex advanceddatagrid

我遇到了一个问题,即我的子元素在图表中与自身一起移动,在图表中它有多个不同级别的父级。这有点奇怪,我认为这可能是用于说明它是相同元素的功能,但它在我的数据网格中看起来有时会从网格中分离出来!

编辑:我知道这是因为我使用相同的对象,但我想在两个位置都使用相同的对象,这样当我点击任何一个时,我就会得到相同的dg.selectedItem。我正在寻找一种方法来阻止树内运动发生在两个对象而不是一个(如果可能),而不是使用不同的对象。

我已将其简化为此代码以说明问题:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               creationComplete="init()">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;

            [Bindable] var ac:ArrayCollection;

            public function init():void
            {
                ac = new ArrayCollection();
                var objWithMultipleParents:Object = {name:"Awkward family tree"};
                ac.addItem({
                    name:"Parent 1",
                    children:[
                        objWithMultipleParents,
                        {name:"Child of Parent 1"}  
                    ]
                });
                ac.addItem({
                    name:"Parent 2",
                    children:[
                        {name:"Child of Parent 2",children:[objWithMultipleParents]},
                        {name:"Child #2 of Parent 2"}
                    ]
                });
            }

        ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="dg" width="100%" height="100%">
        <mx:dataProvider>
            <mx:HierarchicalData source="{ac}" />
        </mx:dataProvider>
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="name" headerText="Groups"/>
        </mx:columns>
    </mx:AdvancedDataGrid>
</s:Application>

在扩展父母2的孩子1之前:

Before expanding Child 1 of Parent 2

扩展父母2的孩子1后:

After expanding Child 1 of Parent 2

有没有办法阻止这种情况?

3 个答案:

答案 0 :(得分:1)

答案是否定的。您无法在多个地方显示相同的项目。你会遇到像你上面提到的那样的小怪癖。但是,您可以显示该项目的平面副本,然后使用某种形式的唯一标识符访问该项目。

//store item reference in accessible object
obj = new Object();
obj[itemRef.uid] = itemRef;

//copy enough information to display and re-access correctly
copy1.name = itemRef.name;
copy1.uid = itemRef.uid;
parent1.add(copy1);

copy2.name = itemRef.name;
copy2.uid = itemRef.uid;
parent2.add(copy2);

//on item selection, access it through uid
itemRef = obj[dg.selectedItem.uid];

如果您没有任何类型的UID,并且不想创建一个UID,您也可以将平面副本用作项目键。

//make copies
copy1.name = itemRef.name;
copy2.name = itemRef.name;
parent1.add(copy1);
parent2.add(copy2);

//map references
obj[copy1] = itemRef;
obj[copy2] = itemRef;

//re-access
itemRef = obj[dg.selectedItem];

答案 1 :(得分:1)

树中的任何节点只能在树中出现一次。期。 节点的引用(对象ID)标识它在树中的位置。多次添加将破坏需要知道树在节点中的位置的所有机制。只有相反的方式才能起作用(知道哪个节点处于某个位置)。其中一个副作用是错误的缩进。当显示节点的子节点时,计算所需的缩进并将其应用于其外观 - 无论它们是否处于完全不同的缩进级别,都应该在树中出现。

如果需要在不同位置显示相同的数据,请使树节点成为包含数据的对象的包装器。 树ndoes是独立的对象,但是从它们引用的对象中获取它们的名称,图标,工具提示,警告。这个数据对象&#39;可以由任意数量的树节点引用。 即使需要知道单击了哪些数据,也可以从消息中获取对树节点的引用,并从中获取对数据对象的引用,以便进一步处理。

答案 2 :(得分:0)

好的,这是你的问题。

var objWithMultipleParents:Object = {name:"Problem"};

您正在创建一个对象并在多个位置使用 在AS3中,对象通过引用传递 如果您在一个元素中更改对象,则表示您正在“全部”更改它 请注意,在我的示例中,我使用一个函数来创建一个新对象,而不是一遍又一遍地引用相同的对象。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    minWidth="955" minHeight="600"
               creationComplete="init()">
<mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;

        [Bindable]
        public var ac:ArrayCollection;

        public function init():void
        {
            ac = new ArrayCollection();
            var objWithMultipleParents:Object = createObject( );
            ac.addItem({
                name:"Parent 1",
                children:[
                    objWithMultipleParents,
                    {name:"Child of Parent 1"}  
                ]
            });
            ac.addItem({
                name:"Parent 2",
                children:[
                    {name:"Child of Parent 2",children:[createObject( )]},
                    {name:"Child #2 of Parent 2"}
                ]
            });
        }
        public function createObject( ):Object{
            return {name:"Problem"}
        }

    ]]>
</mx:Script>

<mx:AdvancedDataGrid id="dg" width="100%" height="100%">
    <mx:dataProvider>
        <mx:HierarchicalData source="{ac}" />
    </mx:dataProvider>
    <mx:columns>
        <mx:AdvancedDataGridColumn dataField="name" headerText="Groups"/>
    </mx:columns>
</mx:AdvancedDataGrid>

您也可以查看HierarchicalData