Apache flex Flex:树组件:在数据提供程序更新时保持状态

Apache flex Flex:树组件:在数据提供程序更新时保持状态,apache-flex,actionscript-3,flex3,Apache Flex,Actionscript 3,Flex3,如何保持树控件的状态? 我希望在更新树的数据提供程序时保持树的状态,而不是使其崩溃。我认为没有办法自动执行此操作(尽管我从未使用过树控件)。我认为最好的办法是扩展树控件,自己处理状态记录 例如,我可能会重写data属性,以便在组件上设置新数据对象之前可以运行状态检查函数。查看帮助有以下几种方法 isItemOpen(item:Object):Boolean, 及 您需要递归地运行每个节点,检查它是否打开并存储该节点的状态。然后,当它使用新的数据提供程序重新绘制时,递归地运行新节点,检查是否有

如何保持树控件的状态?
我希望在更新树的数据提供程序时保持树的状态,而不是使其崩溃。

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

例如,我可能会重写data属性,以便在组件上设置新数据对象之前可以运行状态检查函数。查看帮助有以下几种方法

isItemOpen(item:Object):Boolean, 


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

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

例如,我可能会重写data属性,以便在组件上设置新数据对象之前可以运行状态检查函数。查看帮助有以下几种方法

isItemOpen(item:Object):Boolean, 


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

类似这样的情况如何:

var openItems:Object = tree.openItems; tree.dataProvider = myNewDataProvider; tree.openItems = openItems; tree.validateNow(); var openItems:Object=tree.openItems; tree.dataProvider=myNewDataProvider; tree.openItems=openItems; tree.validateNow();
如果新的数据提供程序与旧的数据提供程序完全不同,我不确定这会有多好,但当您懒洋洋地加载树节点时,它会起作用。

类似这样的情况如何:

var openItems:Object = tree.openItems; tree.dataProvider = myNewDataProvider; tree.openItems = openItems; tree.validateNow(); var openItems:Object=tree.openItems; tree.dataProvider=myNewDataProvider; tree.openItems=openItems; tree.validateNow();
如果新的数据提供程序与旧的数据提供程序完全不同,我不确定这会有多好,但是当你懒洋洋地加载树节点时,它会起作用。

这实际上相当容易做到。您只需确保组件绑定到其数据提供程序,而不仅仅是引用它。因此,在mxml中,这是用于分配数据提供程序的花括号语法。此外,DP必须是[可绑定的]

如果执行此操作,则无论何时更新(添加节点、删除、重命名或其他)数据提供程序,它都会在控件中自动更新。无需手动失效或更新


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

这实际上相当容易做到。您只需确保组件绑定到其数据提供程序,而不仅仅是引用它。因此,在mxml中,这是用于分配数据提供程序的花括号语法。此外,DP必须是[可绑定的]

如果执行此操作,则无论何时更新(添加节点、删除、重命名或其他)数据提供程序,它都会在控件中自动更新。无需手动失效或更新


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

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


希望这是有意义的。

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


希望这是有意义的。

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


有关IUID的更多信息:

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


关于IUID的更多信息:

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


.

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


.

以下是我如何让它工作的。关键是调用

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

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

这将使你的整个树保持开放

下面是我如何让它工作的。关键是调用

*yourTreeInstance*.validateDisplayList();
更新后