Flex:树组件:数据提供者更新时保持状态

发布于 2024-07-13 12:16:48 字数 47 浏览 5 评论 0原文

我将如何保持树控件的状态? 我想在数据提供者更新时保持树的状态,而不是崩溃。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

忆依然 2024-07-20 12:16:48

像这样的事情怎么样:

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

如果新的 dataProvider 与旧的 dataProvider 完全不同,我不确定这会工作得如何,但是当您延迟加载树节点时它会起作用。

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.

场罚期间 2024-07-20 12:16:48

这是我如何让它发挥作用的。 关键是

*yourTreeInstance*.validateDisplayList();

在更新树的数据提供者后调用。 我的代码如下:

<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)"/>

这将使您的整个树保持打开状态。

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.

不羁少年 2024-07-20 12:16:48

这实际上很容易做到。 您只需确保组件绑定到其 dataProvider,而不仅仅是引用它。 因此,在 mxml 中,这是用于分配 dataProvider 的大括号语法。 另外,DP 必须是[可绑定]。

如果您这样做,则每当您更新(添加节点、删除、重命名等)数据提供程序时,它将在您的控制中自动更新。 无需手动失效或更新。

如果您需要实际的代码示例,请告诉我。

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.

给不了的爱 2024-07-20 12:16:48

对于使用 BlazeDS 的项目,我必须在不破坏用户体验的情况下更新和重新加载树组件数据(重新加载数据时所有节点都会关闭)。
而不是密切关注“之前打开过哪个节点?” 以及“滚动位置是什么?” 我找到了一种将 Tree 组件数据的新状态注入到现有数据提供程序中的方法。

如果您有兴趣,请阅读此处的文章

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.

苍暮颜 2024-07-20 12:16:48

我认为没有办法自动执行此操作(尽管我从未使用过树控件)。 我认为你最好的选择是扩展树控制并自己处理状态记录。

例如,我可能会覆盖数据属性,以便您可以在组件上设置新数据对象之前运行状态检查函数。 查看帮助中有一些方法

isItemOpen(item:Object):Boolean, 

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

您需要递归地运行每个节点并检查它是否打开并存储该节点的状态。 然后,当使用新的数据提供程序重新绘制时,递归地运行新节点并检查它们中是否有任何先前打开过,如果是,则展开它们。

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.

逆光飞翔i 2024-07-20 12:16:48

您需要在代表节点的数据对象上实现 IUID 接口。 UID 是一个唯一标识符,通常只是根据对象中的数据构建的,但有时覆盖它并使其成为在数据提供程序刷新之间保持不变的 GUID 会更准确。 因此,如果 UID 匹配,则在使用新的数据提供程序时,上述内容将起作用。

希望这是有道理的。

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.

万人眼中万个我 2024-07-20 12:16:48

Inferis 的答案涉及存储 openItems,然后在更新数据提供程序后再次设置它们,并结合在 dataprovider 数组集合中的对象上实现 IUID 接口,对我有用。

有关 IUID 的更多信息:http://livedocs.adobe .com/flex/3/html/help.html?content=about_dataproviders_8.html

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

动次打次papapa 2024-07-20 12:16:48

为了让以下代码片段

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

正常

callLater(keepOpenStateItems);

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

工作,您必须遵循 mattbilson 和 Michelle 的建议。 他们是绝对正确的。

刚刚实现了树 dataprovider 中包含的对象的 IUID,瞧!
集合刷新使树真正保持在之前的状态。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文