Flex: компонент дерева: сохранение состояния при обновлении поставщика данных - PullRequest
1 голос
/ 15 февраля 2009

Как мне сохранить состояние контроля дерева? Я хотел бы сохранить состояние дерева, когда его поставщик данных обновляется, а не сворачивается.

Ответы [ 8 ]

3 голосов
/ 15 февраля 2009

Как насчет этого:

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

Я не уверен, насколько хорошо это будет работать, если новый dataProvider радикально отличается от старого, но он работает, когда вы лениво загружаете узлы дерева.

2 голосов
/ 29 июля 2011

Вот как у меня это получилось. Ключ должен вызвать

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

Это сохранит все дерево открытым.

1 голос
/ 29 августа 2010

Для проекта с BlazeDS мне приходилось работать с обновлением и перезагрузкой данных компонента Tree, не нарушая пользовательский интерфейс (все узлы закрывались при перезагрузке данных). Вместо того, чтобы следить за тем, «какой узел был открыт раньше?» И «какова позиция прокрутки?», Я нашел способ внедрить новое состояние данных компонента дерева в существующий поставщик данных.

Прочтите статью здесь, если вы заинтересованы .

1 голос
/ 25 февраля 2009

Это на самом деле довольно легко сделать. Вам просто нужно убедиться, что Компонент связан с его dataProvider, а не просто ссылаться на него. Итак, в mxml это синтаксис фигурных скобок для назначения dataProvider. Кроме того, DP должен быть [Bindable].

Если вы сделаете это, каждый раз, когда вы обновляете (добавляете узлы, удаляете, переименовываете, что угодно) ваш провайдер данных, он автоматически обновляется в вашем контроле. Не требуется ручная аннулирование или обновление.

Если вам нужен пример кода, дайте мне знать.

0 голосов
/ 09 августа 2013

В следующем фрагменте

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

или

callLater(keepOpenStateItems);

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

чтобы работать, вы должны следовать советам Мэтбилсона и Мишель. Они абсолютно правы.

Только что реализовал IUID объекта, который содержится в дереве поставщика данных и вуаля! Обновление коллекции сохраняет дерево в том состоянии, в котором оно было раньше.

0 голосов
/ 04 августа 2010

Ответ Inferis, включающий сохранение openItems и последующую настройку их после обновления поставщика данных, в сочетании с реализацией интерфейса IUID для объектов в коллекции массива провайдера данных, работал для меня.

Дополнительная информация о IUID: http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_8.html

0 голосов
/ 15 декабря 2009

Вам необходимо реализовать интерфейс IUID для ваших объектов данных, которые представляют ваши узлы. UID - это уникальный идентификатор, который обычно создается из данных объекта, но иногда более корректно переопределить это и сделать его GUID, который сохраняется между обновлениями поставщика данных. Таким образом, вышеуказанное будет работать при использовании нового поставщика данных, если идентификаторы совпадают.

Надеюсь, что это имело смысл.

0 голосов
/ 15 февраля 2009

Я не думаю, что есть способ сделать это автоматически (хотя мне никогда не приходилось использовать элемент управления деревом). Я думаю, что вам лучше всего расширить контроль над деревом и самостоятельно управлять записью состояния.

Например, я бы, возможно, переопределил свойство данных, чтобы вы могли запустить функцию проверки состояния, прежде чем устанавливать новый объект данных в компоненте. Глядя на помощь есть методы

isItemOpen(item:Object):Boolean, 

и

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

Вам нужно рекурсивно пройти через каждый узел и проверить, открыт ли он, и сохранить состояние для этого узла. Затем, когда он будет перерисован с новым поставщиком данных, рекурсивно пропустите новые узлы и проверьте, были ли какие-либо из них ранее открыты, и если они были, разверните их.

...