родительские данные, рассчитанные из дочерних полей в иерархической структуре данных - PullRequest
1 голос
/ 17 июня 2009

В flex 3 у меня есть иерархическая структура данных. Я хотел бы отобразить его содержимое в виде дерева. Моя проблема в том, что у меня есть узлы, данные которых рассчитываются от дочерних узлов. Как структурировать иерархию для автоматического изменения этих родительских узлов, если изменились данные их детей? Например:

  • Каждый узел имеет флаг предупреждения. Если некоторые из флагов предупреждения о детях изменились на true, родительский флаг предупреждения должен автоматически измениться на true.
  • Целочисленное поле узла является суммой дочерних целочисленных полей, и если какой-либо из дочерних полей изменяется, родительское целочисленное поле "немедленно" вычисляет сумму.

Есть ли простое решение, когда хорошие структурирующие изменения происходят автоматически, или я должен сделать несколько пользовательских функций?

Спасибо!

1 Ответ

0 голосов
/ 17 июня 2009

Мы делаем это, следуя этой схеме:

  1. Создайте метод для вычисления значения в родительском классе и сделайте его привязанным к событию.
  2. В родительском объекте добавьте прослушиватель событий, когда изменяется дочерняя коллекция. Для этого дочерняя коллекция должна быть ArrayCollection или аналогичной.
  3. При перехвате события изменения вызывать (или условно повышать) событие, прикрепленное к метаданным Bindable для метода, упомянутого в шаге 1.

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

Вот пример:

public class Parent
{
    private var children:ArrayCollection = new ArrayCollection();

    public function Parent()
    {
        children.addEventListener(
            CollectionEvent.COLLECTION_CHANGE, 
            function(evt:CollectionEvent):void
            {
                if (...)
                {
                    dispatchEvent(new Event("warningStateChanged"));
                }
            }
        );
    }

    [Bindable("warningStateChanged")]
    public function containsWarnings():Boolean
    {
        for each (var child:Child in children)
        {
            if (child.hasWarning)
            {
                return true;
            }
        }
        return false;
    }
}
...