<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Go!Verla Flex Blog &#187; Flex</title>
	<atom:link href="http://tearaway-tea.com/blog/category/flex/feed/ru/" rel="self" type="application/rss+xml" />
	<link>http://tearaway-tea.com/blog</link>
	<description>от Евгения Тютюнника</description>
	<lastBuildDate>Mon, 31 Aug 2009 04:21:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Вращение блудного сильверлайтера</title>
		<link>http://tearaway-tea.com/blog/2009/08/%d0%b2%d1%80%d0%b0%d1%89%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b1%d0%bb%d1%83%d0%b4%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%b8%d0%bb%d1%8c%d0%b2%d0%b5%d1%80%d0%bb%d0%b0%d0%b9%d1%82%d0%b5%d1%80%d0%b0/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/08/%d0%b2%d1%80%d0%b0%d1%89%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b1%d0%bb%d1%83%d0%b4%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%b8%d0%bb%d1%8c%d0%b2%d0%b5%d1%80%d0%bb%d0%b0%d0%b9%d1%82%d0%b5%d1%80%d0%b0/ru/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 03:55:29 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=334</guid>
		<description><![CDATA[Привет ребята, пишу вам из далёкой Калифорнии, куда забросила судьба меня и мою жену. Так получилось, что я, очень резко, из флексера-страдальца превратился в счастливого сильверлайтера. Все мои коллеги уже успели получить от меня тонны положительных отзывов о данной технологии. Мой энтузиазм в описании всех фичей Silverlight и до сих пор не угасает. Правда, у [...]]]></description>
			<content:encoded><![CDATA[<p>Привет ребята, пишу вам из далёкой Калифорнии, куда забросила судьба меня и мою жену. Так получилось, что я, очень резко, из флексера-страдальца превратился в счастливого сильверлайтера. Все мои коллеги уже успели получить от меня тонны положительных отзывов о данной технологии. Мой энтузиазм в описании всех фичей Silverlight и до сих пор не угасает. Правда, у меня возникла диллема: мой блог был расчитан на аудиторию флексеров, и это было бы опрометчиво, просто изменить тематику статей — поэтому так долго и не писал.</p>
<p><span id="more-334"></span><br />
В Silverlight все отлично, начиная от возможности писать код на всех языках из семьи .NET (ну, конечно же, самый популярный это красавец С#), заканчивая продуманной иерархией визуальных компонентов и возможности их полного видоизменения. Двусторонний биндинг, LINQ, нормальная поддержка ООП, Expression Blend как средство, прошу заметить, удобного «design mode» и т.п.</p>
<p>Есть и некоторые проблемные места, которые во Flex работают из коробки, например невозможность использовать свои курсоры, отсутствие чего-то на подобии PopUpManager, и нативного drag-n-drop. Но это все делается довольно быстро вручную.</p>
<p>В общем, я бы уже и смирился бы с мыслью, что Flex удел мучеников и желающих и далее подставлять костыли в индуский вонючий код, как был просто повержен беглым анализом новых фичей беты Flex 4!</p>
<p>Это был катарсис, оказывается в Adobe не все заснули в двухлетнюю спячку, оказывается они поняли, что раз Microsoft, возможно и своровали идею MXML, binding и вообще флекса как технологии (отмывши это все от толстого слоя ила из берегов Ганга), им ничего не мешает сделать то же самое. И вот, пожалуйста, новый фреймворк визуальных компонентов Spark, который один к одному копирует подход Template Design-а в архитектуре контролов Silverlight, это подробнее обсудим в следующих статьях. Вот тебе и пока-что хромающий Flash Catalyst, идеологическое подобие Expression Blend, вот тебе и новый язык векторной разметки на основе MXML — FXG!, точная копия набора примитивов из XAML (Rect, Ellipse, GradientFill и т.п.). Без которого немыслимо то самое разделение труда дизайнера и программиста.</p>
<p>Мало того, после просмотра исходного кода спарковских контролов, у меня возникло впечатление, что его писали уже люди, а не человеко-недели. Это же можно читать! Подозреваю, что Adobe всё-таки наняла нормальных архитекторов и программистов из штатов. Что конечно достойно глубокого поклона с моей стороны.</p>
<p>В общем, я несказанно счастлив, что теперь есть в чём разбиратся дальше. И что, возможно, вернусь в лоно флекса, как тот самый библейский блудный сын. Конечно же, как говорится, что-бы победить нужно узнать все слабости врага, чем, можно сказать, я сейчас и занимаюсь. Пожалуй в этом контексте и попробую написать несколько статей, не просто сравнивая Silverlight и Flex (слава Богу, сейчас это уже возможно), а рассматривая конкретные подходы в проектировании приложений, которые можно применять на обеих платформах. До встречи, друзья.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/08/%d0%b2%d1%80%d0%b0%d1%89%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b1%d0%bb%d1%83%d0%b4%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%b8%d0%bb%d1%8c%d0%b2%d0%b5%d1%80%d0%bb%d0%b0%d0%b9%d1%82%d0%b5%d1%80%d0%b0/ru/feed/ru/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Инвалидация свойств невизуальных объектов</title>
		<link>http://tearaway-tea.com/blog/2009/04/%d0%b8%d0%bd%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d0%be%d0%b9%d1%81%d1%82%d0%b2-%d0%bd%d0%b5%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d1%85-%d0%be%d0%b1/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/04/%d0%b8%d0%bd%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d0%be%d0%b9%d1%81%d1%82%d0%b2-%d0%bd%d0%b5%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d1%85-%d0%be%d0%b1/ru/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 14:58:47 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Action Script]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=311</guid>
		<description><![CDATA[Наверно, следовало бы сначала описать своё понимание паттерна «Инвалидация чего-либо» во Flex. Может быть напишу статью о полезности такого подхода в разработке визуальных компонентов. В общем, возможно, вы часто используете пару методов invalidateProperties() / commitProperties() для отложеного выполнения логики set методов свойств ваших компонентов. Эта пара определена в базовом для всех Flex контролов классе UIComponent.
Краткий [...]]]></description>
			<content:encoded><![CDATA[<p>Наверно, следовало бы сначала описать своё понимание паттерна «Инвалидация чего-либо» во Flex. Может быть напишу статью о полезности такого подхода в разработке визуальных компонентов. В общем, возможно, вы часто используете пару методов <em>invalidateProperties()</em> / <em>commitProperties()</em> для отложеного выполнения логики set методов свойств ваших компонентов. Эта пара определена в базовом для всех Flex контролов классе UIComponent.</p>
<p>Краткий смысл паттерна в том, что мы ожидаем присваивание значений набору свойств компонента в течение одного кадра Flash Player-а, а последующюю логику обработки этих значений переносим на следующий кадр. Это может повысить производительность приложения, а так же навести порядок в обработке значений связанных между собой свойств компонента.</p>
<p>Полагаю, что инвалидация свойств компонентов во Flex практикуется потому, что большинство компонентов инстанциируется посредством MXML и порядок присваивания свойств спрогнозировать невозможно.</p>
<p>Но, на практике, возникаются ситуации, когда подобный механизм нужен и в невизуальных объектах, например элементах модели бизнес-логики, которые приходят от сервера.</p>
<p><span id="more-311"></span><br />
Я подготовил простой <a title="Properties Invalidation" href="http://tearaway-tea.googlecode.com/svn/trunk/propertiesInvalidation/index.html">пример</a>, который демонстрирует суть задачи.</p>
<p>Допустим у нас есть класс модели <a title="OpportunityDTO" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/propertiesInvalidation/src/com/tearaway_tea/model/OpportunityDTO.as">OpportunityDTO</a>, экземпляры которого получаются от сервера и создаются AMF десериализатором Flash Player-а, который нам не подконтролен. В нём есть два свойства <em>date</em>, <em>children</em>, в момент присваивания значений которых, нам нужна дополнительная обработка. Эта обработка должна выполняться только тогда, когда оба свойства получили свои значения. Типичный случай для паттерна инвалидации свойств.</p>
<pre><code>package com.tearaway_tea.model
{
	import flash.events.EventDispatcher;

	import mx.collections.ArrayCollection;

	import org.goverla.interfaces.IPropertiesInvalidable;
	import org.goverla.managers.PropertiesInvalidationManager;

	public class OpportunityDTO extends EventDispatcher implements IPropertiesInvalidable
	{
		public function get date() : Date
		{
			return _date;
		}

		public function set date(value : Date) : void
		{
			_date = value;
			_dateChanged = true;
			invalidateProperties();
		}

		public function get children() : ArrayCollection
		{
			return _children;
		}

		public function set children(value : ArrayCollection) : void
		{
			_children = value;
			_childrenChanged = true;
			invalidateProperties();
		}

		public function invalidateProperties() : void
		{
			PropertiesInvalidationManager.instance.invalidateProperties(this);
		}

		public function commitProperties() : void
		{
			if (_dateChanged &amp;&amp; _childrenChanged)
			{
				_dateChanged = false;
				_childrenChanged = false;

				for each (var item : ItemDTO in children)
				{
					item.name += "/" + date.toString();
				}
			}
		}

		private var _date : Date;

		private var _dateChanged : Boolean;

		private var _children : ArrayCollection;

		private var _childrenChanged : Boolean;
	}
}</code></pre>
<p>Для решения этой задачи я предлагаю использовать синглтон <a title="PropertiesInvalidationManager" href="http://code.google.com/p/goverla/source/browse/trunk/goverla/src/org/goverla/managers/PropertiesInvalidationManager.as">PropertiesInvalidationManager</a>, который работает по образу и подобию флексовского LayoutManager-а.</p>
<pre><code>package org.goverla.managers
{
	import mx.rpc.AsyncDispatcher;

	import org.goverla.interfaces.IPropertiesInvalidable;

	public class PropertiesInvalidationManager
	{
		public static function get instance() : PropertiesInvalidationManager
		{
			if (_instance == null)
			{
				_instance = new PropertiesInvalidationManager();
			}
			return _instance;
		}

		private static var _instance : PropertiesInvalidationManager;

		public function invalidateProperties(target : IPropertiesInvalidable) : void
		{
			if (_targets.indexOf(target) &lt; 0)
			{
				_targets.push(target);

				if (_dispatcher == null)
				{
					_dispatcher =
						new AsyncDispatcher(commitProperties, [], 0);
				}
			}
		}

		public function commitProperties() : void
		{
			for each (var target : IPropertiesInvalidable in _targets)
			{
				target.commitProperties();
			}
			_targets = [];
			_dispatcher = null;
		}

		private var _targets : Array = [];

		private var _dispatcher : AsyncDispatcher;

	}
}</code></pre>
<p>Суть очевидна. Менеджер получает ссылку на объект, который нуждается в инвалидации свойств, ставит его в очередь и на следующем кадре вызывает у него <em>commitProperties()</em>. Для откладывания выполнения используется флексовский AsyncDispatcher, который основан на Timer.</p>
<p>Для удобства использования, можна создать какой-то базовый класс, который будет имплементировать интерфейс IPropertiesInvalidable.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/04/%d0%b8%d0%bd%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d0%be%d0%b9%d1%81%d1%82%d0%b2-%d0%bd%d0%b5%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d1%85-%d0%be%d0%b1/ru/feed/ru/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Моя презентация с iForum 2009</title>
		<link>http://tearaway-tea.com/blog/2009/04/%d0%bc%d0%be%d1%8f-%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-iforum-2009/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/04/%d0%bc%d0%be%d1%8f-%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-iforum-2009/ru/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 14:42:28 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=274</guid>
		<description><![CDATA[Согласно сообщению от организаторов, форум посетило около 1200 человек. Большинство из них мало интересовалось потоком «Интернет-Технологии», что логично, так как в основном аудитория состояла из специалистов по рекламе, владельцев украинских интернет компаний, а также людей, мечтающих о владении подобными и прочих «интернет-дельцов».
Но, несмотря на немногочисленную аудиторию, я с удовольствием посмотрел и послушал выступление создателя библиотеки [...]]]></description>
			<content:encoded><![CDATA[<p>Согласно сообщению от организаторов, форум посетило около 1200 человек. Большинство из них мало интересовалось потоком <a title="«Интернет-Технологии»" href="http://iforum.com.ua/programma-tech/">«Интернет-Технологии»</a>, что логично, так как в основном аудитория состояла из специалистов по рекламе, владельцев украинских интернет компаний, а также людей, мечтающих о владении подобными и прочих «интернет-дельцов».</p>
<p>Но, несмотря на немногочисленную аудиторию, я с удовольствием посмотрел и послушал выступление создателя библиотеки <a title="Away3D" href="http://away3d.com/">Away3D</a>, Александра Задорожного, как часть доклада «Трёхмерные вебсайты и вебсервисы: возможности, преимущества и перспективы». Он, довольно грустно поведал о разочаровании последней версией Flash Player 10 на предмет отсутствия ожидаемой полной поддержки 3D, а не только базового функционала. Сказал, что забросил своё детище, хотя и удивлён тем, что, проект Away3D так долго существует (связывает это с низкой функциональностю API Flash Player-а).</p>
<p>Мою презентацию можно прокликать <a title="To Flex or Not To Flex" href="http://www.slideshare.net/tearaway_Tea/to-flex-or-not-to-flex">он-лайн</a>. Вроде бы будет и видео с выступления (но как часто бывает, после окончаний конференций уже некогда и незачем подобным заниматься).</p>
<div id="__ss_1238619" style="width: 500px; text-align: left;"><object width="500" height="417" data="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=iforum2009-flexair-090402074243-phpapp01&amp;rel=0&amp;stripped_title=to-flex-or-not-to-flex" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=iforum2009-flexair-090402074243-phpapp01&amp;rel=0&amp;stripped_title=to-flex-or-not-to-flex" /><param name="allowfullscreen" value="true" /></object></div>
<p>По уже сложившейся «традиции», после моего выступления Сергей Байдачный из Microsoft рассказал о Silverlight. На этот раз о новых фичах третьей беты. Вообще, мне очень интересна тема разработки на Silverlight (думаю, как и большинству сознательных флексеров). Flex до сих пор сложно назвать самым крутым средством для RIA, ввиду забивания со стороны Adobe на большинство вопросов программистского характера (рефакторинг, логичной и управляемой снаружи ООП моделью базовых компонентов, возможности языка Action Script). Так как Silverlight является наследником крутейших средств и методологий .NET-а, то он априори — крут, крут, крут.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/04/%d0%bc%d0%be%d1%8f-%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-iforum-2009/ru/feed/ru/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Пример использования Mate Flex Framework</title>
		<link>http://tearaway-tea.com/blog/2009/03/usage-example-of-mate-flex-framework/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/03/usage-example-of-mate-flex-framework/ru/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 21:45:04 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=183</guid>
		<description><![CDATA[Сразу же после появления на свет вышеуказанного фреймворка я описал своё первое впечатление о нём. В нашем большом приложении корпоративного уровня мы его успешно используем и по сей день.
Некоторые коллеги постоянно норовят разузнать все детали и нюансы использования Mate на практике и в связи с этим я решил описать пример типового архитектурного решения основанного на [...]]]></description>
			<content:encoded><![CDATA[<p>Сразу же после появления на свет вышеуказанного фреймворка я <a href="http://tearaway-tea.com/blog/2008/09/5-копеек-о-mate-flex-framework/">описал</a> своё первое впечатление о нём. В нашем большом приложении корпоративного уровня мы его успешно используем и по сей день.</p>
<p>Некоторые коллеги постоянно норовят разузнать все детали и нюансы использования <em><a title="Mate Flex Framework" href="http://mate.asfusion.com/">Mate</a></em> на практике и в связи с этим я решил описать пример типового архитектурного решения основанного на модели реального приложения. Он похож на примеры с сайта фреймворка, но расписан пошагово с конкретными рекомендациями на всех уровнях.</p>
<p><span id="more-183"></span>Итак, я подготовил <a href="http://code.google.com/p/tearaway-tea/">проект</a> <strong><em>opportunities</em></strong> (так сказать, подающий большие надежды) на <em>Google Code</em> с доступными <a href="http://code.google.com/p/tearaway-tea/source/browse/#svn/trunk/opportunities">исходниками</a>. Для начала рассмотрим его <a href="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/index.html">он-лайн</a>:</p>
<p><a href="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/index.html"><img class="alignnone" title="Opportunities" src="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/images/opportunities.png" alt="" width="600" height="300" /></a></p>
<p>У нас есть список сущностей с возможностью редактирования каждой из них в отдельной форме, а также добавлять новые — проще не бывает. Следующее решение, как всегда покажется необоснованно сложным для подобного примера, но незабываем, что перед нами стоит задача ознакомления с <em>Mate</em>, а не написания примера в 25 строк экшен-скрипта.</p>
<p>Я использую, так называемую схему <em>«двустороннего коммуницирования посредством модели и инжектинга»</em>, на сайте фреймворка есть отличная диаграма как этого так и других приёмов:</p>
<p><a href="http://Mate.asfusion.com/page/documentation/diagrams"><img class="alignnone" title="Two-way communication via model: Using view injection" src="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/images/two_way_view_injection.png" alt="" width="594" height="629" /></a></p>
<p>Рассмотрим каждый элемент диаграмы основываясь на классах моего примера. Пункт 3 исключаем, так как для доступа к серверу мы используем специальный класс сервиса OpportunitiesMockService наследуемый от ServiceBase (я уже <a title="Паттерн для работы с RemoteObject" href="http://tearaway-tea.com/blog/2009/02/оптимальный-паттерн-для-работы-с-remoteobject/">описывал этот приём</a> ранее).</p>
<h3>Model</h3>
<p>Я определил три класса модели. Самый элементарный, зависимый от представления, класс элемента списка <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/model/OpportunityVO.as">OpportunityVO</a>. Второй класс <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/data/OpportunitiesDataProvider.as">OpportunitiesDataProvider</a>, является списком экземпляров OpportunityVO, он инкапсулирует в себе вызовы серверных методов и для удобства наследуется от ArrayCollection. Это даёт возможность использовать его провайдером данных для большинства списочных компонентов из Flex фреймворка.</p>
<p>Третий — <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/data/OpportunityDataProvider.as">OpportunityDataProvider</a>, предназначен для работы с конкретным редактируемым OpportunityVO из списка. У него есть публичное свойство <em>opportunity</em>, а также методы для манипуляций с ним. Этот класс диспатчит события <em>opportunityCreated</em> и <em>opportunitySaved</em> типа DataProviderEvent, которые информируют о завершении обработки opportunity (так как эти действия зачастую связаны с вызовом серверных методов, мы неможем ожидать их синхронного выполнения в потоке вызова методов класса). Реализация класса очень простая, но в реальности, в него нужно помещать все трансформации, инициализации и прочие процедуры над элементом, которые не связаны с логикой работы представления, и вполне успешно могут быть отделены от него.</p>
<p><img class="alignnone" title="Model Diagram" src="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/images/model.png" alt="" width="481" height="265" /></p>
<p>Так же есть вспомогательный класс <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/data/OpportunityViewState.as">OpportunityViewState</a>, который используется для хранения информации о текущей видимой форме в представлении. Подобные классы приходится создавать для решения коммуникационных нюансов <em>Mate</em>, далее я их детально опишу.</p>
<h3>View</h3>
<p>Для представления также определены три класса, первый <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/views/OpportunitiesListView.mxml">OpportunitiesListView</a> для показа списка элементов. У него есть одно публичное свойство <em>dataProvider</em>, а также, он диспатчит два события <em>createOpportunity</em> и <em>editOpportunity</em> типа OpportunityEvent, которые говорят сами за себя.</p>
<p>Второй класс <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/views/OpportunityEditView.mxml">OpportunityEditView</a> определяется свойством <em>opportunity</em>, в которое нужно присваивать непосредственно объект редактирования OpportunityVO, а также он диспатчит другие два события <em>saveOpportunity</em> и <em>closeOpportunity</em> также типа OpportunityEvent.</p>
<p>Третий — <a title="Class Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/views/Index.mxml">Index</a>, является композицией предыдущих. В нём доступно свойство <em>selectedIndex</em>, которое определяет текущую видимую форму.</p>
<p><img class="alignnone" title="View Diagram" src="http://tearaway-tea.googlecode.com/svn/trunk/opportunities/images/view.png" alt="" width="481" height="283" /></p>
<p>Это наше представление. Как видим, его классы наследуются от стандартных контейнеров Flex фрейворка, они не имеют зависимостей от провайдеров данных модели, являются пассивными и выглядят как довольно самодостаточные компоненты для повторного использования — то, что нам и нужно.</p>
<h3>Mate Event Maps</h3>
<p>Перейдём непосредственно к роли <em>Mate</em> в связывании модели и представления. Все декларации этого фреймворка описываются в так называемых <em>«картах событий»</em>. Это MXML файлы, которые поддерживают биндинг и все остальные удобства <em>Flex Builder-а</em>. По мере увеличения проекта, эти карты довольно сильно разростаются, так что для разных групп коммуникаций я завожу отдельные файлы. В данном примере их четыре.</p>
<p>Одна из карт — <a title="Map Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/maps/DataInjectionMap.mxml">DataInjectionMap</a>, описывает связи между представлением и моделью, выполняется только один раз при запуске приложения. Это частичная реализация паттерна <em>IoC (Inversion of Control)</em>, которая работает необычным образом: при необходимости, она создаёт только экземпляры классов модели и слушая события родительского Application, в момент создания представлений, выполняет описанные связывания. Типичная нотация с использованием тегов Injectors и PropertyInjector:</p>
<pre><code>&lt;Injectors
	target="{OpportunitiesListView}"&gt;
 	&lt;PropertyInjector
		targetKey="dataProvider"
		source="{OpportunitiesDataProvider}" /&gt;
&lt;/Injectors&gt;</code></pre>
<p>Здесь мы задаем связь на основе биндинга между экземплярами классов OpportunitiesListView и OpportunitiesDataProvider посредством свойства <em>dataProvider</em>, данные которого в результате попадут в DataGrid.</p>
<p>Остальные: <a title="Map Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/maps/OpportunitiesEventMap.mxml">OpportunitiesEventMap</a>, <a title="Map Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/maps/DataProviderEventMap.mxml">DataProviderEventMap</a>, <a title="Map Definition" href="http://code.google.com/p/tearaway-tea/source/browse/trunk/opportunities/src/com/tearaway_tea/opportunities/maps/NavigationEventMap.mxml">NavigationEventMap</a>, непосредственно описывают действия, которые должны происходить при попадении в поле видимости <em>Mate (Event Bus)</em> каких-либо событий как из представления так и из классов модели. Например, нотация с использованием тегов EventHandlers, MethodInvoker и EventAnnouncer:</p>
<pre><code> &lt;EventHandlers
	type="{OpportunityEvent.EDIT_OPPORTUNITY}"&gt;
 	&lt;MethodInvoker
		generator="{OpportunityDataProvider}"
		method="editOpportunity"
		arguments="{[event.data]}"/&gt;
 	&lt;EventAnnouncer
		type="{NavigationEvent.NAVIGATE_EDIT_VIEW}"
		generator="{NavigationEvent}"/&gt;
&lt;/EventHandlers&gt;</code></pre>
<p>Это выражение читается так: в тот момент когда представление продиспатчит событие <em>editOpportunity </em>(по-сути нажатие кнопки Edit), у экземпляра класса модели OpportunityDataProvider должна запуститься операция редактирования экземпляра класса OpportunityVO, которые доступен из события.</p>
<p>Так же, посылается специальное событие NavigationEvent, в результате которого представление должно переключиться в режим редактирования. Внутри класса OpportunityDataProvider, должен произойти вызов серверного метода для получение экземпляра OpportunityVO с последним состоянием элемента (но в моём примере, я упростил схему, и сохраняю в свойстве <em>opportunity</em> модели, тот же объект). Далее, так как мы указали связывание<em> (injection)</em> в DataInjectionMap между OpportunityEditView и OpportunityDataProvider по свойству opportunity, редактируемый элемент будет доступен в представлении.</p>
<p>В свойствах <em>generator</em> или <em>source</em> вышеописанных тегов, мы указываем класс модели, не экземпляр этого класса. <em>Mate</em> автоматически создаст экземпляр в нужный момент, причём, по-умолчанию, только один раз. Фреймворк имеет внутренний кеш для всевозможных экземпляров модели или событий, и ищет там необходимые объекты для повторного использования. Эта схема похожа на паттерн <em>Singleton</em>, но она гораздо практичнее, так как нет лишнего связывания между сущностями системы, которые неизбежны при использовании <em>«одиночек»</em> (кстати, довольно сильный недостаток прочих фреймворков типа <em>Cairngorm</em> или <em>PureMVC</em>).</p>
<p>И напоследок, рассмотрим специфику карты NavigationEventMap, в которой описаны ответные действия на события NavigationEvent. В общем-то, переключение режимов представления могло бы быть реализовано непосредственно в нём. Но, как показала практика, в больших проектах, визуально легче контролировать подход внешнего управления представлением. Например, если необходимо подключить <em>deep-linking </em>(поддержку изменения адресной строки броузера), мы введём ещё один тип событий BrowserNavigationEvent, которые будут использовать уже готовые списки действий в картах <em>Mate</em>. Итак, нотация:</p>
<pre><code>&lt;EventHandlers
	type="{NavigationEvent.NAVIGATE_EDIT_VIEW}"&gt;
 	&lt;MethodInvoker
		generator="{OpportunityViewState}"
		method="setSelectedIndex"
		arguments="{[1]}" /&gt;
&lt;/EventHandlers&gt;</code></pre>
<p>При попадении в <em>Mate</em> события <em>navigateEditView</em>, вызывается метод у вспомогательного класса модели OpportunityViewState, который является проксирующим. Я не хотел бы вводить для этих целей этот класс, а бы присваивал значения в <em>selectedIndex</em> прямо в классе представления Index, но в свойство <em>generator</em> тега MethodInvoker (как и всех других тегов), нельзя указывать классы визуальных компонентов (то-есть можно, но это будет неправильно, так как фреймворк создаст экземпляр, недоступный никому). Суть в том, что, как я уже писал выше, <em>Mate</em> не создаёт экземпляры визуальных компонентов(и не пытается, это делает MXML), он слушает события всего приложения, и когда компонент попадёт в <em>display list</em> флеш плеера, фреймворк начинает с ним «сотрудничать» (зачастую для определения (<em>injection</em>) зависимостей). Получается, что есть внутренний кеш всех созданных классов самим фреймворком и отдельный список компонентов, которыми заведует сам флеш плеер и они не пересекаются между собой.</p>
<p>Вот и всё. Информацию о всех доступных тегах фреймворка можна найти в <a title="Mate's Tags Description" href="http://mate.asfusion.com/page/documentation/tags">документации</a> на сайте <em>Mate</em>. Надеюсь описание не получилось чересчур запутанным. С удовольствием отвечу на все адекватные вопросы по теме.</p>
<p>P.S. Кстати, на днях вышло обновление <em>Mate</em> до версии <em>0.8.7</em>, в котором появилась возможность задавать связи (<em>injection</em>) между интерфейсами.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/03/usage-example-of-mate-flex-framework/ru/feed/ru/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Оптимальный паттерн для работы с RemoteObject</title>
		<link>http://tearaway-tea.com/blog/2009/02/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d0%bf%d0%b0%d1%82%d1%82%d0%b5%d1%80%d0%bd-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-remoteobject/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/02/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d0%bf%d0%b0%d1%82%d1%82%d0%b5%d1%80%d0%bd-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-remoteobject/ru/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 14:03:45 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Action Script]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=139</guid>
		<description><![CDATA[В продолжение темы советов новичкам, поведаю о самом удобном способе инкапсуляции вызовов серверных методов. Назовём этот паттерн ServiceBase, по-сути это базовый класс, от которого должны наследоваться ваши сервисы (наборы методов, соответствующие серверным):

class ServiceBase
{
	public function ServiceBase(destination : String,
		resultHandler : Function = null, faultHandler : Function = null)
	{
		_resultHandler = resultHandler;
		_faultHandler = faultHandler;

		_remoteObject = new RemoteObject(destination);
	}

	protected function call(name [...]]]></description>
			<content:encoded><![CDATA[<p>В продолжение темы <a title="Советы новичкам" href="http://tearaway-tea.com/blog/2008/12/советы-новичкам/">советов новичкам</a>, поведаю о самом удобном способе инкапсуляции вызовов серверных методов. Назовём этот паттерн ServiceBase, по-сути это базовый класс, от которого должны наследоваться ваши сервисы (наборы методов, соответствующие серверным):<br />
<span id="more-139"></span></p>
<pre><code>class ServiceBase
{
	public function ServiceBase(destination : String,
		resultHandler : Function = null, faultHandler : Function = null)
	{
		_resultHandler = resultHandler;
		_faultHandler = faultHandler;

		_remoteObject = new RemoteObject(destination);
	}

	protected function call(name : String, args : Array) : void
	{
		CursorManager.setBusyCursor();

		var operation : AbstractOperation = _remoteObject.getOperation(name);
		operation.addEventListener(ResultEvent.RESULT, onResult);
		operation.addEventListener(FaultEvent.FAULT, onFault);
		operation.send.apply(operation, args);
	}

	protected function onResult(event : ResultEvent) : void
	{
		CursorManager.removeBusyCursor();

		if (_resultHandler != null)
		{
			_resultHandler(event.result);
		}
	}

	protected function onFault(event : FaultEvent) : void
	{
		CursorManager.removeBusyCursor();

		if (_faultHandler != null)
		{
			_faultHandler(event.fault);
		}
	}

	private var _resultHandler : Function;

	private var _faultHandler : Function;

	private var _remoteObject : RemoteObject;
}</code></pre>
<p>Я иногда наблюдал подобные подходы в коде западных коллег, но схема была несколько иная, менее удобная. Навскидку, данный класс нам ни о чём не говорит, но в паре с таким классом, должно всё проясниться:</p>
<pre><code>class GuestbookService extends ServiceBase
{
	public function GuestbookService(resultHandler : Function = null,
		faultHandler : Function = null)
	{
		super("GuestbookAction", resultHandler, faultHandler);
	}

	public function getGuestbookEntries() : void
	{
		call("getGuestbookEntries", arguments);
	}

	public function getEntryById(id : Number) : void
	{
		call("getEntryById", arguments);
	}

	public function updateEntry(id : Number, text : String) : void
	{
		call("updateEntry", arguments);
	}
}</code></pre>
<p>Этот класс я называю сервисом по работе с гостевой книгой. В нём есть все те же методы, что и в серверном классе GuestbookAction (гейтвее или сервлете, в зависимости от платформы). В конструктор можно передать ссылки на функции, которые получат ответ от сервера или информацию о ошибке. Пример использования:</p>
<pre><code>new GuestbookService().updateEntry(5, "Nice solution!");</code></pre>
<p>или</p>
<pre><code>new GuestbookService(onGetEntryById).getEntryById(6);

function onGetEntryById(result : GuestbookEntry) : void
{
	_list.addItem(result);
}</code></pre>
<p>Основной принцип заключается в том, что мы не сохраняем ссылку на экземпляр класса GuestbookService, после того, как он отработает запрос — он нам не нужен. Этот факт можно использовать при множественном вызове серверного метода, каждный раз создавая новый экземпляр сервиса.</p>
<p>Мне этот подход нравится больше чем низкоуровневое конструирование запроса на основе RemoteObject своей прозрачностью и простотой. Так же, подобные наследники можно и следует генерировать автоматически на основе серверных классов. Тогда, вы получаете полный контроль над соответствием названий серверных методов, а так же их сигнатур. Компилятор просто не соберёт ваш проект, если вы не исправите ошибку.</p>
<p>Так же, подобное решение может вам помочь при юнит-тестировании, подменяя базовый класс чем-то вроде MockServiceBase.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/02/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d0%bf%d0%b0%d1%82%d1%82%d0%b5%d1%80%d0%bd-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-remoteobject/ru/feed/ru/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flex Formatter</title>
		<link>http://tearaway-tea.com/blog/2009/02/flex-formatter/ru/</link>
		<comments>http://tearaway-tea.com/blog/2009/02/flex-formatter/ru/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 12:06:43 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=126</guid>
		<description><![CDATA[Наверно многие уже слышали и проверили как работает долгожданный плагин для форматирования кода Action Script и разметки MXML — Flex Formatter (http://flexformatter.sourceforge.net/). Но, тем не менее, версия 0.6.7 не включала в себя таких жизненно важных параметров как кол-во пробелов около символа «:» и т.п., а так же имела очень мрачную панель управления.
На прошедших выходных я [...]]]></description>
			<content:encoded><![CDATA[<p>Наверно многие уже слышали и проверили как работает долгожданный плагин для форматирования кода <em>Action Script</em> и разметки <em>MXML </em>— <em><strong><span style="font-style: normal;">Flex Formatter</span> </strong></em>(<a href="http://flexformatter.sourceforge.net/">http://flexformatter.sourceforge.net/</a>). Но, тем не менее, версия <em>0.6.7</em> не включала в себя таких жизненно важных параметров как кол-во пробелов около символа «:» и т.п., а так же имела очень мрачную панель управления.</p>
<p>На прошедших выходных я решил связаться с разработчиком плагина  Ернестом. Он оказался очень отзывчивым человеком. Мы обменялись с ним некоторым опытом разработки на <em>Action Script</em> и он пообещал доработать плагин и поправить панель настроек.</p>
<p>Сегодня утром, я обнаружил новую версию <em>0.6.8</em>, которая практически идеальна. Всем рекомендую к использованию, что-бы ваш код был сексуален как никогда ранее.</p>
<p>А так же, не забывайте все претензии добавлять в <a href="https://sourceforge.net/tracker2/?func=browse&amp;group_id=248408&amp;atid=1126569">баг-трекер</a> проекта. Слава Богу, автор очень отзывчивый и оперативный.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2009/02/flex-formatter/ru/feed/ru/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Советы новичкам</title>
		<link>http://tearaway-tea.com/blog/2008/12/%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%bd%d0%be%d0%b2%d0%b8%d1%87%d0%ba%d0%b0%d0%bc/ru/</link>
		<comments>http://tearaway-tea.com/blog/2008/12/%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%bd%d0%be%d0%b2%d0%b8%d1%87%d0%ba%d0%b0%d0%bc/ru/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 14:12:32 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=119</guid>
		<description><![CDATA[В основном это список произвольных мелких нюансов без сортировки и развития. Рекомендуется к быстрому прочтению, что-бы задействовалось подсознание :-).

Реализация itemRenderer-ов для грида
Никогда не ленитесь и создавайте все свои рендереры наследуя UIComponent или соответствующих контролов Label, CheckBox, TextInput. Никогда не используйте в рендерерах Box, Canvas — они безбожно тормозят.
Что такое mxml?
Что-бы понять суть, добавте параметр -keep-generated-actionscript компилятору флекса. [...]]]></description>
			<content:encoded><![CDATA[<p>В основном это список произвольных мелких нюансов без сортировки и развития. Рекомендуется к быстрому прочтению, что-бы задействовалось подсознание :-).<br />
<span id="more-119"></span></p>
<h3>Реализация itemRenderer-ов для грида</h3>
<p>Никогда не ленитесь и создавайте все свои рендереры наследуя UIComponent или соответствующих контролов Label, CheckBox, TextInput. Никогда не используйте в рендерерах Box, Canvas — они безбожно тормозят.</p>
<h3>Что такое mxml?</h3>
<p>Что-бы понять суть, добавте параметр <em>-keep-generated-actionscript</em> компилятору флекса. После этого большинство вопросов как это работает, когда допустим биндинг и т.п. исчезнут сами собой.</p>
<h3>Слушание событий</h3>
<p>По возможности всегда подписывайтесь на события через mxml. Это плохой код:</p>
<pre><code>private function onCreationComplete() : void {
	listView.addEventListener(RotatorsEvent.NEW_ROTATOR, baseEventsHandler);
	listView.addEventListener(RotatorsEvent.EDIT_ROTATOR, baseEventsHandler);
	listView.addEventListener(RotatorsEvent.DELETE_ROTATOR, baseEventsHandler);
	editView.addEventListener(RotatorsEvent.SAVE_ROTATOR, baseEventsHandler);
	editView.addEventListener(RotatorsEvent.CANCEL_ROTATOR, baseEventsHandler);
}

private function baseEventsHandler(event : RotatorsEvent) : void {
	switch (event.type) {
		case RotatorsEvent.NEW_ROTATOR : newRotatorAction(); break;
		case RotatorsEvent.EDIT_ROTATOR : editRotatorAction(); break;
		case RotatorsEvent.SAVE_ROTATOR : saveRotatorAction(event); break;
		case RotatorsEvent.DELETE_ROTATOR : deleteRotatorAction(); break;
		case RotatorsEvent.CANCEL_ROTATOR :
		default  : currentState = LIST_VIEW_STATE;
	}
}</code></pre>
<p>Нужно писать так:</p>
<pre><code>&lt;view:RateCardListToolBar
	newRateCard="onNewRateCard(event)"
	loadRateCardSimpleItems="onLoadRateCardSimpleItems(event)"
	editRateCard="onEditRateCard(event)"/&gt;</code></pre>
<h3>Жизненный цикл компонента</h3>
<p>Обязательно найдите время для знакомства с очерёдностью и смыслом методов <em>invalidateProperties()</em>, <em>commitProperties()</em>, <em>measure()</em>, <em>invalidateDisplayList()</em>, <em>updateDisplayList()</em> и т.п. Не нужно пытаться что-либо рисовать в объекте <em>graphics</em> в конструкторе, для этого есть другое, более удачное место. Интересуйтесь!</p>
<h3>Используйте code-behind</h3>
<p>Зачастую использование тега &lt;mx:Script /&gt; допустимо только тогда, когда в нём будет не более одного-двух екранов кода. Если у вас огромный компонент обязательно выносите код в отдельный базовый класс:</p>
<pre><code>Component.mxml:
&lt;ComponentBase
	xmlns="*"
	xmlns:mx="http://www.adobe.com/2006/mxml"&gt;
	&lt;mx:Button
		label="button"
		click="onClick()" /&gt;
&lt;/ComponentBase&gt;

ComponentBase.as:
package
{
	import mx.controls.Alert;

	public class ComponentBase
	{
		protected function onClick() : void
		{
			Alert.show("Я буду больше интересоваться внутренностями флекса",
				"Напоминание");
		}
	}
}</code></pre>
<h3>Event handlers</h3>
<p>По-момему, нет ничего лучше чем называть методы хендлеров по такому конвеншену:</p>
<p>Для MouseEvent.CLICK — метод:</p>
<pre><code>onClick(event : MouseEvent) : void</code></pre>
<p>Для ListEvent.CHANGE для объекта с <em>id=&#8221;customComponent&#8221;</em> — метод:</p>
<pre><code>onCustomComponentChange(event : ListEvent) : void</code></pre>
<h3>Избавляемся от противных предупреждений</h3>
<p>Если у вас накопилось больше нуля предупреждений — срочной начинайте чистку. Вот, кстати, пример нелогичности Action Script, но тем не менее решаемый:</p>
<pre><code>for each (var item : ItemType in items) {
	...code...
}

...code...

for each (var item : ItemType in items) {
	...code...
}</code></pre>
<p>В таком коде вас ожидает <em>Duplicate code definition warning</em>. Исправить можно заменив последний цикл на такое:</p>
<pre><code>for each (item in items) {
	...code...
}</code></pre>
<h3>Непреодолимый public</h3>
<p>Все контролы в компоненте <em>mxml</em> имеют область видимости <em>public</em>, к сожалению так устроен мир. Это не значит что к ним можно свободно обращаться снаружи: <em>customComponent.customButton.label = &#8220;very bad&#8221;</em>, всегда нужно создавать соответствующие гетеры и сетеры: <em>customComponent.buttonLabel = &#8220;very well&#8221;</em>.</p>
<h3>Binding</h3>
<p>Во-первых, его нужно использовать. Подходы типа «Мы любим сами контролировать процесc присваивания данных» — пафос и лишняя головная боль. Пример максимально не эффективного кода:</p>
<pre><code>if (!isExpand)
{
	activeDates.visible = false;
	hiatus.visible = false;
	startAirTime.visible = false;
	endAirTime.visible = false;
	daysAirTime.visible = false;
}
else
{
	activeDates.visible = true;
	hiatus.visible = true;
	startAirTime.visible = true;
	endAirTime.visible = true;
	daysAirTime.visible = true;
}</code></pre>
<p>Нужно всего лишь пометь <em>isExpand</em> как [Bindable] и связать все контролы с ним в <em>mxml</em>.</p>
<h3>Использование for each</h3>
<p>Странно, но многие начинающие флексеры не знают о нём, что приводит к проблемам производительности. Нельзя:</p>
<pre><code>for (var i : int = 0; i &lt; result.length; i++)
{
	result[i].children = rateCard.rateCardsComparison;
}</code></pre>
<p>Нужно:</p>
<pre><code>for each(var item : DataType in result)
{
	item.children = rateCard.rateCardsComparison;
}</code></pre>
<h3>Изменение размера и позиции в updateDisplayList()</h3>
<p>Глянем пример кода:</p>
<pre><code>protected override  function updateDisplayList(unscaledWidth : Number,
	unscaledHeight : Number) : void
{
	super.updateDisplayList(unscaledWidth, unscaledHeight);

	if (horizontalScrollBar != null)
	{
		horizontalScrollBar.x = watchColumnEdge;
		horizontalScrollBar.width = width - watchColumnEdge;
	}
}</code></pre>
<p>Так делать нельзя (диспачатся лишние события), нужно использовать методы <em>move()</em> и <em>setActualSize()</em>.</p>
<h3>Dynamic классы</h3>
<p>Желательно отказаться от использования этого механизма. Только если нужно бысто заполнять коллекции или что-либо объектами типа <em>{label : &#8220;Label&#8221;, handler : onSomething}</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2008/12/%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%bd%d0%be%d0%b2%d0%b8%d1%87%d0%ba%d0%b0%d0%bc/ru/feed/ru/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>To Flex or not to Flex</title>
		<link>http://tearaway-tea.com/blog/2008/09/to-flex-or-not-to-flex/ru/</link>
		<comments>http://tearaway-tea.com/blog/2008/09/to-flex-or-not-to-flex/ru/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 09:52:13 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=91</guid>
		<description><![CDATA[Суть данной статьи заключается в изложении моего опыта по разработке приложений на технологии Flex в разрезе принятий решений о выборе или не выборе онной на конкретных проектах. Да, именно так, очень часто возникают ситуации, когда использование Flex не только невыгодно по временным ограничениям, но и губительно для проекта.

Быстро рассмотрим типы приложений, что бы составить план [...]]]></description>
			<content:encoded><![CDATA[<p>Суть данной статьи заключается в изложении моего опыта по разработке приложений на технологии Flex в разрезе принятий решений о выборе или не выборе онной на конкретных проектах. Да, именно так, очень часто возникают ситуации, когда использование Flex не только невыгодно по временным ограничениям, но и губительно для проекта.</p>
<p><span id="more-91"></span></p>
<p>Быстро рассмотрим типы приложений, что бы составить план обзора и поиска благоприятной почвы для старта разработки на Flex. По-видимому, все интересующие нас приложения уже можно разделить на вебтопные и десктопные. Веб-приложения могут быть обычными или <em>RIA</em>, и каждые из них могут иметь как <em>front-end</em> — собственно внешний сайт, так и <em>back-end</em> — админку. Не забудем так же и о том, что они могут быть как internet — для обычных обывателей сети, так и intranet — для корпоративных пользователей. С помощью механизма <em>Adobe AIR</em>, Flex стал доступен и на десктопе, но там его использование подчинено сходным требованиям как и в вебе.</p>
<h3>Веб-приложения, которые не RIA</h3>
<p>Flex практически никогда не нужен при разработке классических сайтов. Классическими я называю: домашние странички, сайты-визитки, новостные сервисы, форумы, блоги, порталы, социальные сети и т.п. Все, кто пытался реализовать их не на связке <em>HTML</em>+<em>JS</em>, в результате получал негибкую, тяжелую поделку, которая плохо индексируется, плохо рендерит текст, не поддерживает стандартную взаимосвязь с броузером и т.п.</p>
<p>Я участвовал в разработке подобного проекта в компании <a href="http://sonopia.com/">Sonopia</a>. Мы разрабатывали социальную сеть на Flex, которую изначально, под впечатлением тезисов <em>RIA</em>, руководство хотело позиционировать как насыщеную медиа контентом и прочими ультра-штучками. В результате мы получили набор стандартных сервисов: <em>Dashboard</em>, <em>Profile</em>, <em>Photos</em>, <em>Guestbook</em>, которые выглядели как минимум нелепо. В гостевой книге пользователи не могли вставлять теги форматирования текста и ссылки на фотки или флеш виджеты. Перемещение по разделам нормально не синхронизировалось с кнопкой <em>«Back»</em> в броузере. Выполняя минимальный функционал приложение весило 1,5 Мб. В какой-то момент, все заметили что скорость разработки того, что должно быть не Flex, где-то в два раза дольше чем на <em>HTML</em> и большую часть проекта дописывали уже используя стандартные технологии. В результате нам добавилось проблем с синхронизацией обоих частей проекта. Затем команду Flex разработчиков расформировали, а чуть позже старт-ап провалился.</p>
<p>Ещё один пример — портал top4top.ru, пусть он и писался, предусмотрительно, на чистом <em>Action Script</em>, тем не менее это хрестоматийный пример неправильного позиционирования технологии (не говоря уже об <a href="http://flash-ripper.com/archives/002573.php">общей идейной направленности</a>).</p>
<p>Для персонального интереса, во время изучения Flex, я сделал на нём пару стандартных сайтов для группы <a href="http://etwasunders.com/">Etwas Unders</a> (<a href="http://tearaway-tea.com/blog/2007/04/etwasunderscom/">есть описание</a>) и для <a href="http://jmak.com.ua/">студии JMAK</a>. Так как количество разделов и контента было не велико, то они выглядели сносно. Хотя многие посетители недоумевали, зачем там вообще Flex? Согласен — ни к чему. Единственный выигрыш — отсутствие проблем с версткой под основные броузеры (не отрицаю, что для кого-то это будет ключевой бонус).</p>
<p><img class="alignnone size-full wp-image-102" title="Etwas Unders" src="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/etwasunders.jpg" alt="" width="500" height="350" /></p>
<p>Не так давно попалась ссылка на сайт <a href="http://xoalt.com/">http://xoalt.com/</a>, интернет-каталог товаров. Подобные проекты, как и интернет магазины или просто справочники чего-либо вообще запрещено разрабатывать на Flex. Самый главный критерий таких проектов — это высокая доступность поисковым машинам, с чем Flex, как и все флеш-приложения традиционно слабы.</p>
<p><img class="alignnone size-full wp-image-105" title="xoalt" src="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/xoalt.jpg" alt="" width="500" height="350" /></p>
<p>Разработка админок, которые в последнее время часто делают на Flex, так же под вопросом. Если нужна гибкая работа с текстом — будут проблемы, если же вывод табличных данных с необходимостью редактирования, то Flex с AdvancedDataGrid компонентом может помочь быстро справиться с заданием. <em>Drag-n-drop</em> возможен и на <em>JS</em>, но, не спорю, на Flex это можно сделать быстрее и проще.</p>
<h3>RIA</h3>
<p>Как это ни странно, Flex рулит далеко не всегда и в этом лагере тоже. Иногда кажется, что в общем случае флеш плэер используется только для проигрования видео и музыки. Но, скоро ожидается повсемесное использование <em>HTML 5</em> с поддержкой данных штучек, что же, получается Flex так и не найдёт свою стабильную нишу и всегда будет только альтернативой? К счастью не всё так, и есть ряд критериев, при которых Flex просто необходим. Я опишу приблизительные тексты технического задания при котором можно смело выбирать Flex:</p>
<p><em>«Нужно разработать большую кросс-браузерную веб-систему, по мониторингу/управлению/статистике определённых процессов определённого предприятия или продукта. В системе ожидается много иерархических или табличных данных которые нужно сортировать, групировать и редактировать. Нужно запрограммировать более десятка разнообразных форм ввода и изменения данных. Код должен реализовывать практики ООП и быть самодокументированным так как проект долгий и текучка кадров неизбежна.»</em></p>
<p><em>«Нам нужна on-line система по обработке видеосигналов с нескольких источников, а так же соотвествующий UI по базовому редактированию и сохранению контента на сервер.»</em></p>
<p>Можно придумать ещё несколько подобных условий задач, но их будет объединять общий схожий мотив, который и есть ключевым коньком Flex. </p>
<blockquote><p>Flex – это наилучшее средство для разработки веб-приложений с большим количеством форм включая наборы нестандартных контролов ввода, с возможностью их скинования, включая все мультимедийные фичи флеш плеера, на основе легко сопровождаемого объектно-ориентированного программного кода.</p></blockquote>
<p>Так как подобные критерии чаще всего удовлетворяют корпоративные системы, мы и не видим очень много популярных Flex приложений среди известных пользовательских интернет-сервисов. Разве что он-лайн фотошопы и видео-редакторы.</p>
<p>Сейчас, я как раз и занят разработкой подобной корпоративной системы по управлению рекламным контентом на телевидении. Вместо долгих описаний, я приведу пару UI-заготовок, которые должны быть реализованы в сжатые сроки:</p>
<p><img class="alignnone size-full wp-image-93" title="WO" src="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/wideorbit-1.jpg" alt="" width="500" height="325" /></p>
<p><img class="alignnone size-full wp-image-94" title="WO" src="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/wideorbit-2.jpg" alt="" width="500" height="325" /></p>
<p>Думаю, коментарии, почему в данном случае выбран именно Flex излишни. По-сути, вся данная статья — один большой коментарий вызванный данным проектом.</p>
<p>В заключении можно всё резюмировать банальными фразами. Ваша цель как программиста взвесить многие факторы будущего приложения и основываясь на них не выбрать (чаще всего) или выбрать Flex. Если же вас принимают на вакансию Flex программиста в проект, где его роль сомнительна или абсурдна, подумайте обстоятельно, что бы исскуственно не стать <em>«слабым звеном»</em> в глазах нахальных жавистов или гордых сишарпщиков — сотрудников по проекту (и такое на моём опыте бывало).</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2008/09/to-flex-or-not-to-flex/ru/feed/ru/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>5 копеек о Mate Flex Framework</title>
		<link>http://tearaway-tea.com/blog/2008/09/5-%d0%ba%d0%be%d0%bf%d0%b5%d0%b5%d0%ba-%d0%be-mate-flex-framework/ru/</link>
		<comments>http://tearaway-tea.com/blog/2008/09/5-%d0%ba%d0%be%d0%bf%d0%b5%d0%b5%d0%ba-%d0%be-mate-flex-framework/ru/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 14:21:36 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=31</guid>
		<description><![CDATA[До последнего момента я очень скептически относился ко всем существующим фреймворкам для Flex. Я, конечно, не уделял особого внимания изучениям подробностей Cairngorm или PureMVC, но тем не менее мне было известно их основное устройство. Например я презираю глобальную доступность View из любого места в коде проекта написанного с использованием Cairngorm. Так же, меня напрягло количество промежуточных классов PureMVC, от которых код разбухает как на дрожжах. Имеено по-этому я никогда [...]]]></description>
			<content:encoded><![CDATA[<p>До последнего момента я очень скептически относился ко всем существующим фреймворкам для Flex. Я, конечно, не уделял особого внимания изучениям подробностей <a href="http://opensource.adobe.com/wiki/display/cairngorm/">Cairngorm</a> или <a href="http://puremvc.org/">PureMVC</a>, но тем не менее мне было известно их основное устройство. Например я презираю глобальную доступность <em>View</em> из любого места в коде проекта написанного с использованием <em>Cairngorm</em>. Так же, меня напрягло количество промежуточных классов <em>PureMVC</em>, от которых код разбухает как на дрожжах. Имеено по-этому я никогда ничем не пользовался кроме базовой компонентно-событийной системы Flex Framework.</p>
<p>Поддавшись на восторженые отзывы риа-гуру я решил разобратся что и к чему. Не надейтесь, я не собирась тут расписывать по-русски о модели работы <a href="http://mate.asfusion.com/">Mate</a>, я опишу лишь несколькими предложениями: это действительно круто и я отвечаю за свои слова.</p>
<p>Я считаю, успех <em>Mate</em> связан с тем, что это не портированый фреймворк, а написаный именно под Flex. Он использует основные (возможно и не очень правильные) принципы и особенности Flex фреймворка, такие как:</p>
<ul>
<li>наследование всех классов от EventDispatcher, которое позволяет использовать bubbling-события, как основные носители сообщений между <em>View</em>, <em>Model</em> и прочими сущностями;</li>
<li>довольно идентичную особенность биндинга, с помощью которой <em>Mate</em> наладило ненавязчивый <em>IOC</em> (Inversion of Controls);</li>
<li>разметку <em>mxml</em> для описания деклараций связующих механизмов приложения в простой и понятной форме.</li>
</ul>
<p>И все это работает поверх сущностей вашего приложения, без необходимости наследования утомляющих абстрактных классов команд, медиаторов, моделей и пр. Ну и на десерт, <em>Mate</em> фреймворк отлично расширяется путем наследования ваших дополнений от базовых управляющих классов.</p>
<p>В общем, листая документацию сайта, можно получить первое впечатление не более чем за час. Просмотр исходного кода подтвердает подозрения, что авторы проекта — отличные профессионалы, которые обернули нюансы Flex в бонусы. Нужно пользоваться!</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2008/09/5-%d0%ba%d0%be%d0%bf%d0%b5%d0%b5%d0%ba-%d0%be-mate-flex-framework/ru/feed/ru/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Пару слов о MacroContent Builder</title>
		<link>http://tearaway-tea.com/blog/2008/07/%d0%bf%d0%b0%d1%80%d1%83-%d1%81%d0%bb%d0%be%d0%b2-%d0%be-macrocontent-builder/ru/</link>
		<comments>http://tearaway-tea.com/blog/2008/07/%d0%bf%d0%b0%d1%80%d1%83-%d1%81%d0%bb%d0%be%d0%b2-%d0%be-macrocontent-builder/ru/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 14:09:24 +0000</pubDate>
		<dc:creator>tearaway_Tea</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://tearaway-tea.com/blog/?p=72</guid>
		<description><![CDATA[На моей последней работе в голландской компании KZOO webcreatie я разрабатывал AIR приложение для визуального построения шаблонов к некоему серверному движку, которым владеет компания. Приложение предоставляет пользователям набор элементов (список, елемент, контент) для построения гибкой древовидной структуры. Результатом работы есть XML файл, в котором содержится как некоторая скриптовая логика, так и структура БД, а так [...]]]></description>
			<content:encoded><![CDATA[<p>На моей последней работе в голландской компании <a href="http://kzoo.nl/">KZOO webcreatie</a> я разрабатывал <em>AIR</em> приложение для визуального построения шаблонов к некоему серверному движку, которым владеет компания. Приложение предоставляет пользователям набор элементов (список, елемент, контент) для построения гибкой древовидной структуры. Результатом работы есть XML файл, в котором содержится как некоторая скриптовая логика, так и структура БД, а так же и HTML представление. Серверный движок на основе этого файла реализует связь с БД и генерирует конечную HTML страницу. Система довольно универсальная, но, конечно же, не может покрыть узкопрофильные решения, только типовые сайты.</p>
<p><script src="http://tearaway-tea.com/js/swfobject.js" type="text/javascript"></script> <script type="text/javascript"><!--
	var flashvars = {airversion: "1.0", appname: "MacroContent Builder", appurl: "http://tearaway-tea.com/blog/wp-content/uploads/2008/09/mc-builder.air", appid: "com.majoca.Puzzle", imageurl: "http://tearaway-tea.com/blog/wp-content/uploads/2008/09/mc-builder-badge.jpg", hidehelp: "true", str_err_airswf: "Running locally? The AIR proxy swf wont load properly when this demo is run from the local file system."	};
	swfobject.embedSWF("http://tearaway-tea.com/bin/AIRInstallBadge.swf", "mcbuilderairbadgecontent", "215", "180", "9.0.115", "http://tearaway-tea.com/bin/expressinstall.swf", flashvars, {bgcolor : "#FFFFFF"});
// --></script></p>
<div id="mcbuilderairbadgecontent"><strong>Hello, you either have JavaScript turned off or an old version of Adobe’s Flash Player. <a href="http://www.macromedia.com/go/getflashplayer/">Get the latest Flash player</a>.</strong> Application link: <a href="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/mc-builder.air">http://tearaway-tea.com/blog/wp-content/uploads/2008/09/mc-builder.air</a>.</div>
<p>Программа доступна для ознакомительной установки. Наврядли удастся как-то использовать на практике, без соответствующего ПО для серверной стороны.<br />
<span id="more-72"></span></p>
<h3>Некоторые детали</h3>
<p>Интерфейс программы выполнен без дополнительного «скинования». Я не использовал никаких фреймворков. Поддерживается <em>undo</em>/<em>redo</em> для всех операций. Из интересных архитектурных моментов могу описать процесс декларации метаданных для передачи информации в редактор свойств выбранного элемента в дереве.</p>
<p>По-сути, каждый элемент дерева это наследник базового класса TreeNode, в котором объявлены специфические для его типа свойста, например:</p>
<pre style="color:#000000;"><span style="color:#800000; font-weight:bold; ">public</span> <span style="color:#800000; font-weight:bold; ">class</span> PagesBaseNode <span style="color:#800000; font-weight:bold; ">extends</span> TreeNode <span style="color:#800080; ">{</span>

        <span style="color:#808030; ">[</span>Bindable<span style="color:#808030; ">]</span>
        <span style="color:#808030; ">[</span>Serializable<span style="color:#808030; ">]</span>
        <span style="color:#808030; ">[</span>Editable<span style="color:#808030; ">(</span>group<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">General</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> dependentGroup<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">Page</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> editor<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">CheckBoxEditor</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span>
            label<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">page</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> bindable<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">true</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> index<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">5</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#808030; ">]</span>
        <span style="color:#800000; font-weight:bold; ">public</span> function get page<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span> <span style="color:#808030; ">:</span> Boolean <span style="color:#800080; ">{</span>
            <span style="color:#800000; font-weight:bold; ">return</span> _page<span style="color:#808030; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#800000; font-weight:bold; ">public</span> function set page<span style="color:#808030; ">(</span>value <span style="color:#808030; ">:</span> Boolean<span style="color:#808030; ">)</span> <span style="color:#808030; ">:</span> <span style="color:#800000; font-weight:bold; ">void</span> <span style="color:#800080; ">{</span>
            _page <span style="color:#808030; ">=</span> value<span style="color:#808030; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#808030; ">[</span>Serializable<span style="color:#808030; ">]</span>
        <span style="color:#808030; ">[</span>Editable<span style="color:#808030; ">(</span>group<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">Page</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> editor<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">StringEditor</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> label<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">start template:</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> index<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">0</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#808030; ">]</span>
        <span style="color:#800000; font-weight:bold; ">public</span> function get startTemplate<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span> <span style="color:#808030; ">:</span> String <span style="color:#800080; ">{</span>
            <span style="color:#800000; font-weight:bold; ">return</span> _startTemplate<span style="color:#808030; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#800000; font-weight:bold; ">public</span> function set startTemplate<span style="color:#808030; ">(</span>value <span style="color:#808030; ">:</span> String<span style="color:#808030; ">)</span> <span style="color:#808030; ">:</span> <span style="color:#800000; font-weight:bold; ">void</span> <span style="color:#800080; ">{</span>
            _startTemplate <span style="color:#808030; ">=</span> value<span style="color:#808030; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#808030; ">[</span>Serializable<span style="color:#808030; ">]</span>
        <span style="color:#808030; ">[</span>Editable<span style="color:#808030; ">(</span>group<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">Page</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> editor<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">CollectionEditor</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> label<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">aliases:</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span>
            itemsEditor<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">TwoStringsEditor</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> itemsClass<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">PageAliasEntry</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span>
            itemField1<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">alias</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> itemField2<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">target</span><span style="color:#800000; ">"</span><span style="color:#808030; ">,</span> index<span style="color:#808030; ">=</span><span style="color:#800000; ">"</span><span style="color:#0000e6; ">1</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#808030; ">]</span>
        <span style="color:#800000; font-weight:bold; ">public</span> function get pageAliases<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span> <span style="color:#808030; ">:</span> ArrayCollection <span style="color:#800080; ">{</span>
            <span style="color:#800000; font-weight:bold; ">if</span> <span style="color:#808030; ">(</span>_pageAliases <span style="color:#808030; ">==</span> <span style="color:#0f4d75; ">null</span><span style="color:#808030; ">)</span> <span style="color:#800080; ">{</span>
                _pageAliases <span style="color:#808030; ">=</span> <span style="color:#800000; font-weight:bold; ">new</span> ArrayCollection<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#808030; ">;</span>
            <span style="color:#800080; ">}</span>
            <span style="color:#800000; font-weight:bold; ">return</span> _pageAliases<span style="color:#808030; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#800000; font-weight:bold; ">private</span> <span style="color:#800000; font-weight:bold; ">var</span> _page <span style="color:#808030; ">:</span> Boolean<span style="color:#808030; ">;</span>

        <span style="color:#800000; font-weight:bold; ">private</span> <span style="color:#800000; font-weight:bold; ">var</span> _startTemplate <span style="color:#808030; ">:</span> String<span style="color:#808030; ">;</span>

        <span style="color:#800000; font-weight:bold; ">private</span> <span style="color:#800000; font-weight:bold; ">var</span> _pageAliases <span style="color:#808030; ">:</span> ArrayCollection;
    <span style="color:#800080; ">}</span></pre>
<p>С помощью метаданных Serializable я указываю какое значение нужно сохранять в результирующем XML, блок Editable описывает тип редактора, подпись, позицию в наборе, а также, если свойство имеет списочный тип — класс элементов списка и названия полей в которые будут сохранятся значения.</p>
<p>Данное решение очень удобно тем, что при наличии более 10 типов элементов дерева в среднем с 5 уникальными свойствами в каждом из них, я избегаю разработки массы различных форм с разными наборами идентичных контролов для редактирования. При каждом выборе элемента дерева, редактор свойств, используя Repeater, генерирует набор из стандартных, предварительно запрограммированных редакторов: StringEditor, CheckboxEditor, CollectionEditor, TwoStringsEditor etc.</p>
<p><img class="size-full wp-image-73" title="editors" src="http://tearaway-tea.com/blog/wp-content/uploads/2008/09/editors.png" alt="TreeNode Properties Editor" width="439" height="318" /></p>
<p>Cчитывание метаданных из объекта — дело техники, это не сложно.</p>
<p>Я подумывал о том, что-бы вычленить базовые классы TreeEditor, TreeArrow и TreeNode как отдельную <em>open source</em> библиотеку. А так же, можно добавить код по обработке метаданных элементов дерева и редактора свойств туда же. Если в коментариях отпишется хотя-бы один человек, кому бы это пригодилось — я это сделаю.</p>
<p>На разработку, в общей сложности и в одиночку, я потратил 6 месяцев. Первые четыре на программирование, вторые два на исправление ошибок. Заказчик очень доволен и не хочет останавливаться на достигнутом. Я, правда, не уверен буду ли я учавствовать в этом продолжении.</p>
]]></content:encoded>
			<wfw:commentRss>http://tearaway-tea.com/blog/2008/07/%d0%bf%d0%b0%d1%80%d1%83-%d1%81%d0%bb%d0%be%d0%b2-%d0%be-macrocontent-builder/ru/feed/ru/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
