среда, февраля 20, 2008

Внутренности Flex Framework. Жизненный цикл компонента. Flex

Статья Добрался до самого вкусного — внутренности Flex Framework навела на очень важный документ, расставляющий многие точки над i, которые до этого валялись где-то в области догадок. Итак, источник вот он. Всё в чём я сомневаюсь, буду помечать знаком (#?) где #- ID сомнения (для последующего комментирования).

Жизненный цикл компонента. Дисплей-лист.
  • Во Flex многие элементы размещаются (1?) в дисплей-листе (который мы используем для доступа к ним). Это:
    - внедряемые шрифты
    - стили
    - размер прогрывателя (2?)
    - верхушка (головной элемент) DOM (3?)
  • Доступ к этим элементам осуществляется через SystemManager.
  • При создании, компоненты не имеют доступа к дисплей-листу.
    - свойство компонента systemManager == null
  • Поэтому, конструктор вашего компонента не имеет доступа к этим элементам.

var randomWalk:UIComponent = new RandomWalk();
randomWalk.dataProvider = dataSet;
/* Random Walk cannot access the player’s size, or add capture phase event listeners until addChild is called because systemManager ==null */
addChild(randomWalk);
/* After addChild(), systemManager !=null */

Жизненный цикл компонента. Application.

  • Объект Application - особый случай.
  • Он также не видит (4?) дисплей-лист. Но...
  • ... systemManager != null, хотя
    - stage == null
    - root == null
  • Он не видит дисплей-лист до тех пор, пока не наступит событие creationComplete.
    - в следствии чего, и ваш компонент тоже не видит дисплей-лист.
  • Дисплей-лист становится доступным, когда генерируется событие applicationComplete.
  • Всё это делается в целях улучшения производительности.
  • Тут легко ошибиться.
  • Используйте systemManager.stage (то только не в конструкторе).

Жизненный цикл компонента. Создание экземпляра компонента.

var myComp:UIComponent = new RandomWalk();
myComp.dataProvider = dataSet;

addChild(myComp);

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

public function RandomWalk() {
…}
public function set dataProvider() {…}

  • Подготавливает начальную установку (или начальный набор ?) стилей (5?).
  • Добавляет в дисплей-лист.
  • Генерирует событие preInitialize.

protected function createChildren() {…}

  • Инициализирует accessibility-свойства объекта (6?), если таковые имеют место.
  • Генерирует событие initialize.

Жизненный цикл компонента. Несколько правил.

  • Не добавлять объекты в конструкторе.
    - это не вызовет ошибки, но делать так - не очень эффективно
    - лучше всего переопределить метод createChildren() и делать это в нём
  • Не вызывать метод getStyle() в конструкторе.
    - он вызовет ошибки, но может выдать некорректные данные
    - подождать до createChildren()
    - а еще лучше, переопределить метод commitProperties()
  • Не обращаться к systemManager, stage или root из конструктора.
    - они все равны null
    - лучше подождать до createChildren() или более поздних выводов
  • Не используйте прямой доступ к stage и root
    - используйте systemManager

Жизненный цикл компонента. Запуск. Инициализация.

  1. Создан экземпляр Application.
  2. Установлен Application.systemManager.
  3. Application.dispatchEvent(new Event(‘preinitialize’))
  4. Application.createChildren()
    1. Создан экземпляр randomWalk
    2. Вызван конструктор randomWalk()
    3. Установлены свойства этого компонента
    4. randomWalk.dispatchEvent(new Event(‘preInitialize’))
    5. randomWalk добавлен в приложение (но его всё еще нет в дисплей-листе)
    6. randomWalk .createChildren()
    7. randomWalk.dispatchEvent(new Event(‘initialize’))
  5. Application.dispatchEvent(new Event(‘initialize’))

Жизненный цикл компонента. Запуск. Валидация.

  • Фаза 1
    randomWalk.commitProperties()
    Application.commitProperties()
  • Фаза 2
    randomWalk.measure()
    Application.measure()
  • Фаза 3
    Application.updateDisplayList()
    randomWalk.updateDisplayList()
  • Фаза 4
    randomWalk.dispatchEvent(new Event(‘creationComplete’))
    Application. dispatchEvent(new Event(‘creationComplete’))

Жизненный цикл компонента. Запуск. Завершение.

  • Объект Application добавлен в дисплей-лист
  • Application.dispatchEvent(new Event(‘applicationComplete’))


6 комментариев:

Анонимный комментирует...

Ай молодец. Решено — сегодня перевожу и выкладываю вторую часть.

Конечно, если ты ее еще не перевел :)

Unknown комментирует...

Не, еще нет... Работа не дает. Я бы завтра продолжение 1й части перевел (если кто-нть не переведет :) ).

Анонимный комментирует...

Я так понял, ты остановился на половине, перед "Keyboard/Focus Handling". Верно?

Начинаю переводить вторую часть, закончить первую лучше все же тебе :)

Unknown комментирует...

Верно, я так и рассчитывал, по главе в день :)

Unknown комментирует...

"перекрыть метод createChildren()"
-- "переопределить метод createChildren()"

типа терминология

Unknown комментирует...

Пожалуй соглашусь. Только потому, что Гугл по точному запросу "переопределить метод" выдает больше результатов чем "перекрыть метод". Последний термин приемлем, но может быть истолкован (не программистами) двойственно. Кстати, Lingvo вообще это называет "подмена".