actionscript-3apache-flexadvanceddatagrid

How to stop AdvancedDataGrid with HierarchicalData from moving child elements with multiple parents to different levels?


I'm having a problem where my child element is moved together with itself in the chart where it has multiple parents at different levels. This is kind of odd and I think it might be intended functionality to illustrate that it's the same element but it looks off in my data grids and it sometimes detaches itself from the grid!

EDIT : I'm aware that this is because I'm using the same object but I want to use the same object in both locations so that when I click either one I'm getting the same dg.selectedItem. I'm looking for a way to prevent the in-tree movement from happening on both objects instead of one (IF POSSIBLE), not use different objects.

I've simplified it down to this code to illustrate the issue:

<?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>

Before expanding child 1 of parent 2:

Before expanding Child 1 of Parent 2

After expanding child 1 of parent 2:

After expanding Child 1 of Parent 2

Is there a way to prevent this?


Solution

  • The answer is no. You can't display the same item in multiple places like you want. You're going to run into little UI quirks like the one you've stated above. You can, however, show flat copies of the item, and then access the item using some form of unique identifier.

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

    If you don't have any kind of UID, and don't want to create one, you could also use the flat copies as item keys.

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