Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Котяра

Оценить эту запись

MXML, Биндинг и другие страшные для ТРУЪ аскриптера вещи. Часть первая.

Запись от Котяра размещена 15.04.2012 в 17:03
Обновил(-а) Котяра 15.04.2012 в 23:55

Вводная часть.

Что же надо чтобы использовать mxml?
1) Заводим флекс проект.
Все примеры я делаю во Flash Builder, но в других IDE, думаю проблем не возникнет
Не пугайтесь - он нужен чтобы подключился framework.swc, всё таки какую-то часть флексовского фрэймворка нам нужно будет использовать.
Затем в опциях компилятора прописываем merged into code и добавляем в Additional compiler options опции
-keep - показывать сгенерённые классы (они будут лежать в bin-debug/generated)
-link-report=report.xml - сформировать файл отчёта, будет в bin-debug/report.xml )
-default-size 800 600 - уставновить размер флэшки.

2) первое приложение.
Так как я назвал проект no_flex_mxml, то билдер сгенерил мне класс no_flex_mxml.mxml в качестве дефолтного.
пусть так и будет.
смотрим содержание:
Код AS3:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:Application>
Видим, что главным классом этого приложения записан s:Application
Видим какие-то xmlns.
Это нэймспесы. По сути это псевдонимы для импортов.
В общем видим, что флекса тут очень много.
Давайте сделаем просто обычный спрайт.
Код AS3:
<?xml version="1.0" encoding="utf-8"?>
<mx:Sprite xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        addedToStage="init();"
        >
    <fx:Declarations>
        <fx:Number id="property" />
    </fx:Declarations>
 
    <fx:Script><![CDATA[
        public function init():void {
            trace("init");
	    property = 10;
        }
    ]]>
    </fx:Script>
    <mx:Sprite id="child" addedToStage="trace('child added');" />
</mx:Sprite>
Интересный момент: в спрайте мы видим свойство
addedToStage - это ещё одна фишка mxml - события генерируемые объектами выглядят как свойства и их значениями является код хэндлеров.
Для того, чтобы работали автогенерации и подсказки, нужно описать правильно собственные события с помощью метатега Event.

<fx: Declarations> - нужен для невизуальных объектов.
Которые не размещаются внутри компонента.
К сожалению, код помещенный выше,
Код AS3:
<mx:Sprite id="child" addedToStage="trace('child added');" />
ошибочный.
Цитата:
'Sprite' declaration must be contained within the <Declarations> tag since it does not implement 'mx.core.IUIComponent'.
Т.е. спрайт не является IUIComponent и не может быть там помещен. В следующей статье, я расскажу как обойти эту неприятность, а пока добавлять спрайт в список отображения будем вручную.

Код AS3:
<?xml version="1.0" encoding="utf-8"?>
<mx:Sprite xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        addedToStage="init();"
        >
    <fx:Declarations>
        <fx:Number id="property" />
        <mx:Sprite id="child" addedToStage="trace('child added');" />
    </fx:Declarations>
 
    <fx:Script><![CDATA[
        public function init():void {
            trace("init");
	    property = 10;
            addChild(child);
        }
    ]]>
    </fx:Script>    
</mx:Sprite>
Посмотрим, что же такого нагенерилось?
Заходим в папочку bin-debug/generated и видим там 3 класса:

_no_flex_mxml-binding-generated.as
Код AS3:
class BindableProperty
{
	/*
	 * generated bindable wrapper for property child (public)
	 * - generated setter
	 * - generated getter
	 * - original public var 'child' moved to '_94631196child'
	 */
 
    [Bindable(event="propertyChange")]
    public function get child():flash.display.Sprite
    {
        return this._94631196child;
    }
 
    public function set child(value:flash.display.Sprite):void
    {
    	var oldValue:Object = this._94631196child;
        if (oldValue !== value)
        {
            this._94631196child = value;
           if (this.hasEventListener("propertyChange"))
               this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this, "child", oldValue, value));
        }
    }
 
	/*
	 * generated bindable wrapper for property property (public)
	 * - generated setter
	 * - generated getter
	 * - original public var 'property' moved to '_993141291property'
	 */
 
    [Bindable(event="propertyChange")]
    public function get property():Number
    {
        return this._993141291property;
    }
 
    public function set property(value:Number):void
    {
    	var oldValue:Object = this._993141291property;
        if (oldValue !== value)
        {
            this._993141291property = value;
           if (this.hasEventListener("propertyChange"))
               this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this, "property", oldValue, value));
        }
    }
 
}
Этот класс отвечает за 2 заведённых в блоке fx свойства:
child и property.
Ничего сверхъестественного и сложного. Просто запомните, заводя свойства в mxml - они в итоге оказываются завернутыми в геттер и сеттер с отсылкой события об изменении.

no_flex_mxml-generated.as
Код AS3:
 public class no_flex_mxml extends flash.display.Sprite {
        [Bindable]
        public var child:flash.display.Sprite;
 
        [Inspectable]
        [Bindable]
        public var property:Number;
 
        //  constructor (non-Flex display object)
        public function no_flex_mxml() {
            super();
 
            _no_flex_mxml_Sprite2_i();
 
            // events
            this.addEventListener("addedToStage", ___no_flex_mxml_Sprite1_addedToStage);
        }
 
 
        //  scripts
        //  <Script>, line 11 - 17 - 
		// Это скрипт который я написал в блоке fx:Script
        public function init():void {
            trace("init");
            property = 10;
            addChild(child);
        }
 
        //	supporting function definitions for properties, events, styles, effects
        private function _no_flex_mxml_Sprite2_i():flash.display.Sprite {
            var temp:flash.display.Sprite = new flash.display.Sprite();
            temp.addEventListener("addedToStage", __child_addedToStage);
            child = temp;
            mx.binding.BindingManager.executeBindings(this, "child", child);
            return temp;
        }
 
 
        public function __child_addedToStage(event:flash.events.Event):void {
            trace('child added');
        }
 
        public function ___no_flex_mxml_Sprite1_addedToStage(event:flash.events.Event):void {
            init();
        }
    }
 
}
Тут, надеюсь, тоже всё понятно.

ну и
no_flex_mxml-interface.as
Код AS3:
public class no_flex_mxml extends flash.display.Sprite
    {
        public function no_flex_mxml() {}
 
        [Bindable]
        public var property : Number;
        [Bindable]
        public var child : flash.display.Sprite;
 
        mx_internal var _bindings : Array;
        mx_internal var _watchers : Array;
        mx_internal var _bindingsByDestination : Object;
        mx_internal var _bindingsBeginWithWord : Object;
 
        include "C:/dev/workspace/no_flex_mxml/src/no_flex_mxml.mxml:11,17";
 
    }}
В итоге в дебаг режиме флэшка весит 7.13 кБ.
Много это или мало - решать вам.
Главное, что можно понять из размера - флексфрэймворка здесь нет)

Специально для этой статьи я завёл публичный репозиторий: https://bitbucket.org/k0t0vich/no_flex_mxml
пошагово - смотрите коммиты.
Всего комментариев 23

Комментарии

Старый 15.04.2012 18:10 GBee вне форума
GBee
 
Аватар для GBee
Очень круто. Требую продолжения!
Старый 15.04.2012 18:51 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
Спасибо за статью. Это просто пример или Вы реально какой-то проект писали (пишите) так? Жду продолжения!
Старый 15.04.2012 19:03 Котяра вне форума
Котяра
 
Аватар для Котяра
Реально пишу проект.
Старый 15.04.2012 19:08 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
Не пугайтесь - он нужен чтобы подключился framework.swc, всё таки какую-то часть флексовского фрэймворка нам нужно будет использовать.
framework.swc можно и к as3 проекту подключить. Ну и все таки лучше было написано не "какую-то", а конкретно биндинги.
Старый 15.04.2012 19:22 Котяра вне форума
Котяра
 
Аватар для Котяра
Там не только биндинги.
Старый 15.04.2012 19:25 alatar вне форума
alatar
 
Аватар для alatar
Конкретно в этом примере, только биндинги.
Старый 15.04.2012 19:57 artcraft вне форума
artcraft
 
Аватар для artcraft
очень хочется увидеть чистый as3 проект с работающим BindingManager а не генерированный mxml комплиятором :~)
А еще лучше выпилить биндинг целиком и запустить его без подключения framework.swc
Обновил(-а) artcraft 15.04.2012 в 20:01
Старый 15.04.2012 20:03 Котяра вне форума
Котяра
 
Аватар для Котяра
Ну в report.xml кроме бингинга есть ещё
Цитата:
mx.core:mx_internal
mx.collections.errors:ItemPendingError
mx.rpc:IResponder
Их наверняка тянет сам биндинг уже, но всё же..
Старый 15.04.2012 20:04 Котяра вне форума
Котяра
 
Аватар для Котяра
Цитата:
а не генерированный mxml комплиятором
Я рассказываю про mxml, а биндингМенеджер в чистом ас3 страшно выгдядит и неудобно. Он в mxml лишь и хорош.
Старый 15.04.2012 20:12 artcraft вне форума
artcraft
 
Аватар для artcraft
тут пример биндинга без мхмл (правда не на флексовом менеджере) и ничего страшного в нём я не вижиу...
Старый 15.04.2012 20:20 Котяра вне форума
Котяра
 
Аватар для Котяра
В вводной статье я давал много ссылок.
Старый 15.04.2012 20:25 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
Вот минимальный пример:
Код AS3:
package
{
	import flash.display.Sprite;
	import mx.events.PropertyChangeEvent; 
 
	public class Binding extends Sprite
	{
		[Bindable]
		public var value:int;
 
		public function Binding()
		{
			super(); 
 
			this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onValueChanged);
 
			value+=5;
		} 
 
		private function onValueChanged(e:PropertyChangeEvent):void
		{
			trace(e.property + ' = ' + e.newValue);
		}
	}
}
Нужно только подключить framework.swc
Цитата:
А еще лучше выпилить биндинг целиком и запустить его без подключения framework.swc
Не вижу смысла зачем это делать, т.к. скомпиленный пример весит менее 1,5 кБ, проще говоря из framework.swc ничего лишнего не тянется. Подключается всего два класса PropertyChangeEvent и PropertyChangeEventKind. Возможно в более сложных случаях еще что-то вкомпилится.
Вот что за сценой:
Код AS3:
public function set value(param1:int) : void
        {
            var _loc_2:* = this._111972721value;
            if (_loc_2 !== param1)
            {
                this._111972721value = param1;
                if (this.hasEventListener("propertyChange"))
                {
                    this.dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "value", _loc_2, param1));
                }
            }
            return;
        }// end function
Тобишь ничего лишнего. Еще можно взглянуть на BindingUtils.

Но вообще к теме это все мало относится.
Старый 15.04.2012 20:39 artcraft вне форума
artcraft
 
Аватар для artcraft
@Inet_PC во, именно это я и хотел увидеть

@Котяра "В вводной статье я давал много ссылок."
пугающее количество ссылок надо будет почитать на досуге
Старый 15.04.2012 21:38 FlashRus вне форума
FlashRus
 
Аватар для FlashRus
Не совсем пойму, в чем конкретно ползеность данной затеи?
Это не критика и тп... хочу познать и возможно в дальнейшем пользвоаться)
Старый 15.04.2012 22:38 carrotoff вне форума
carrotoff
 
Аватар для carrotoff
Хоть и MXML мне выносит мозг, но понравилось! Жду новых подробностей
Старый 16.04.2012 00:00 Котяра вне форума
Котяра
 
Аватар для Котяра
Цитата:
Не совсем пойму, в чем конкретно ползеность данной затеи?
Полезность на самом деле есть и именно в сокрытии реализации.
Биндинг и декларативное описание помогают быстро читать и писать код. Хотя они же его могут и запутать.
Всего хорошего в меру надо.
Старый 18.04.2012 08:43 FlashRus вне форума
FlashRus
 
Аватар для FlashRus
Я требую продолжения банкета!)
Старый 23.04.2012 00:22 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Хех, когда-то тоже об этом думал: http://kb2.adobe.com/community/publi...sid_52670.html
а потом - как-то не знаю. Я разочаровался в mxml шаблонах, но это долгая история.
Старый 30.04.2012 13:58 incvizitor вне форума
incvizitor
 
Аватар для incvizitor
Цитата:
В следующей статье, я расскажу как обойти эту неприятность
можно пока что хотя бы линку? а то я усё жду и жду =)
Старый 30.04.2012 18:23 Lecosson вне форума
Lecosson
После добавления спрайта не могу запустить.
Выдает:
Код:
ReferenceError: Error #1065: Переменная mx.binding::BindingManager не определена.
	at test2/_test2_Sprite2_i()[D:\projects\test2\src\test2.mxml:8]
	at test2()[D:\projects\test2\src\test2.mxml:8]
[SWF] D:\projects\test2\bin-debug\test2.swf - 2,126 bytes after decompression
Что это может быть?
Старый 01.05.2012 00:57 ChuwY вне форума
ChuwY
 
Аватар для ChuwY
Библиотеку с mx.binding подключили?
Старый 01.05.2012 12:21 Котяра вне форума
Котяра
 
Аватар для Котяра
Цитата:
можно пока что хотя бы линку? а то я усё жду и жду
Сорри за задержку, я в отпуске)
Линк на решение в моей репе. Код написал, а до объяснения руки не доходят..
Всё дело в волшебных пузырьках:
Код AS3:
[DefaultProperty("children")]
Старый 08.03.2023 12:14 shaman4d вне форума
shaman4d
 
Аватар для shaman4d
Ой прям потеплело в душе )
 

 


Часовой пояс GMT +4, время: 03:45.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.