2009-02-15 3 views
1

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

+0

Вы устанавливаете совершенно новый dataProvider во время обновления? Например: myTree.dataProvider = myCollection; –

+0

да, я устанавливаю новый dataProvider, у той же базовой структуры просто больше или меньше узлов. – Ronn

ответ

0

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

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

isItemOpen(item:Object):Boolean, 

и

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

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

3

Как о чем-то вроде этого:

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

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

+0

+1 звучит как хороший звонок мне –

+0

звучит отлично для меня тоже, не может заставить этого ублюдка работать. Когда вы говорите, что это должно работать, если dataProvider радикально отличается, что это значит? обновленный провайдер, который я использую, будет иметь новые или удаленные узлы. – Ronn

+0

На самом деле, я только что протестировал его с помощью некоторого кода, который добавляет и удаляет узлы, и, похоже, он работает отлично для меня (есть, по-видимому, некоторый код в дереве, который проверяет, openItems существуют в дереве и отбрасывают любые, которые этого не делают). Каким образом это не работает? – inferis

1

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

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

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

+0

И, состояние сохраняется, очевидно, потому что вы не заменяете dataProvider, просто изменяя. – jason

0

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

Надейтесь, что сделал смысл.

0

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

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

1

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

Read the article here if you are interested.

2

Вот как я заработал. Ключ должен быть вызван

*yourTreeInstance*.validateDisplayList(); 

после обновления dataprovider вашего дерева. Мой код ниже:

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

Это сохранит ваше дерево.

0

Чтобы следующий фрагмент кода

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

или

callLater(keepOpenStateItems); 

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

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

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

Смежные вопросы