Flex: Tree component: keeping state when data provider updates

二次信任 提交于 2020-01-05 16:25:55

问题


How would I go about keeping the state of a tree control? I'd like to keep the state of the tree when it's data provider gets updated, instead of it collapsing.


回答1:


How about something like this :

    var openItems:Object = tree.openItems;
    tree.dataProvider = myNewDataProvider;
    tree.openItems = openItems;
    tree.validateNow();

I'm not sure how well this will work if the new dataProvider is radically different from the old one, but it works when you're lazy loading tree nodes.




回答2:


Here is how I got it working. The key is to invoke

*yourTreeInstance*.validateDisplayList();

after updating your tree's dataprovider. My code below:

<fx:Script>
    <![CDATA[
        [Bindable]
        var treeDataProvider:XML;

        private function onTreeCreated(event:FlexEvent):void{

            // update value with new XML here;
            treeDataProvider = <node name="root">
                                   <node name="child 1">
                                       <node name = "grand child 1"/>
                                   </node>
                                </node>;

            myTree.openItems = treeDataProvider..node;
            myTree.validateDisplayList();
        }

    ]]>
</fx:Script>

<mx:Tree id="myTree" labelField="@name" dataProvider={treeDataProvider} 
         creationComplete="onTreeCreated(event)"/>

This will keep your entire tree open.




回答3:


This is actually fairly easy to do. You just have to make sure that the Component is bound to its dataProvider, rather than just referencing it. So, in mxml, that's curly brace syntax for assigning the dataProvider. Also, the DP has to be [Bindable].

If you do this, any time you update (add nodes, remove, rename, whatever) your data provider, it will be automagically updated in your control. No manual invalidating or updating required.

If you need an actual code example, let me know.




回答4:


For a Project with BlazeDS I had to work with updating and reloading Tree component data without breaking the User Experience (all nodes closed when data reloaded). Instead of keeping tabs on “which node was opened before?” and “what was the scroll-position?” I found a way to inject the new state of the Tree component data into the existing data provider.

Read the article here if you are interested.




回答5:


I don't think there is a way to do this automatically (although i've never had to use the tree control). I would think your best bet would be to extend the tree control and handle the recording of state yourself.

For instance I would possibly override the data property so that you could run a state checking function before you set a new data object on the component. Looking at the help there are methods

isItemOpen(item:Object):Boolean, 

and

expandItem(item:Object, open:Boolean, animate:Boolean = false, dispatchEvent:Boolean = false, cause:Event = null):void

You need to recursively run through each node and check if it's open and storing the state for that node. Then when it has redrawn with the new data provider, recursively run through the new nodes and check to see if any of them were previously open, and if they were, expand them.




回答6:


You need to implement the IUID interface on your data objects that represent your nodes. The UID is a unique identifier that is usually just built off the data in the object, but sometimes it is more accurate to override this and make it some GUID that is persistent between data provider refreshes. So the above will work when using a new dataprovider if the UIDs match.

Hope that made sense.




回答7:


Inferis's answer involving storing the openItems, and then setting them again after the data provider is updated, combined with implementing the IUID interface on the objects in the dataprovider array collection worked for me.

More info on IUID : http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_8.html




回答8:


In order the following snippet

var openItems:Object = tree.openItems;
tree.dataProvider = myNewDataProvider;
tree.openItems = openItems;
tree.validateNow();

or

callLater(keepOpenStateItems);

private function keepOpenStateItems():void {
    tree.openItems = openTreeItems; 
}

to work you must follow mattbilson and Michelle advice. They are absolutely right.

Just implemented the IUID of the object that is contained in the tree dataprovider and voila! The collection refresh keeps the tree really at the state of where it was before.



来源:https://stackoverflow.com/questions/551058/flex-tree-component-keeping-state-when-data-provider-updates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!