Аннотирование классов с помощью собственных метатегов.
В этой статье я попробую пролить свет на одну интересную возможность Flex3. А именно, возможность аннотирования классов ActionScript при помощи собственных метатегов. Например, можно аннотировать класс следующим образом.
package
{
[Bindable]
[Table(name="contact")]
public class Contact
{
[Id]
[Column(name="contact_id")]
public var contactId:int;
[Column(name="first_name")]
public var firstName:String;
[Column(name="last_name")]
public var lastName:String;
}
}
В этом примере, метатег [Bindable] – стандартный, а [Table] ,[Id] и [Column] – наши собственные. Ключ компиляции -keep-as3-metadata позволяет дать инструкцию компилятору какие метатеги надо включить в конечный, скомпилированный, SWF-файл, чтобы мы могли использовать их во время выполнения. Установить ключ компиляции можно в свойствах проекта, в закладке “Flex Compiler”, в поле “Additional compiler arguments”. В нашем случае надо дабавить ключ следующим образом «-keep-as3-metadata+=Table,Id,Column». Обратите внимание что используется именно «+=» а не «=», так как «+=» позволяет сохранить установленные по умолчанию метатеги, такие как [Bindable]. «=» перезапишет их только теми которые мы укажем.
Аннотирование метатегами можно использовать во многих случаях. Всё зависит от вашей фантазии. Например можно организовать мапинг или использовать метатеги для формирования SQL запросов.
Следующий пример позволяет нам прочитать аннотацию класса:
var c:Contact = new Contact();
var xml:XML = describeType(c);
Вот результат для нашего примера, класс Contact.
<type name="models.bo::Contact" base="Object" isDynamic="false" isFinal="false" isStatic="false">
<metadata name="Table">
<arg key="name" value="contact"/>
</metadata>
<extendsClass type="Object"/>
<implementsInterface type="flash.events::IEventDispatcher"/>
<method name="dispatchEvent" declaredBy="models.bo::Contact" returnType="Boolean">
<parameter index="1" type="flash.events::Event" optional="false"/>
</method>
<method name="hasEventListener" declaredBy="models.bo::Contact" returnType="Boolean">
<parameter index="1" type="String" optional="false"/>
</method>
<method name="willTrigger" declaredBy="models.bo::Contact" returnType="Boolean">
<parameter index="1" type="String" optional="false"/>
</method>
<accessor name="lastName" access="readwrite" type="String" declaredBy="models.bo::Contact">
<metadata name="Bindable">
<arg key="event" value="propertyChange"/>
</metadata>
<metadata name="Column">
<arg key="name" value="last_name"/>
</metadata>
</accessor>
<accessor name="firstName" access="readwrite" type="String" declaredBy="models.bo::Contact">
<metadata name="Bindable">
<arg key="event" value="propertyChange"/>
</metadata>
<metadata name="Column">
<arg key="name" value="first_name"/>
</metadata>
</accessor>
<method name="removeEventListener" declaredBy="models.bo::Contact" returnType="void">
<parameter index="1" type="String" optional="false"/>
<parameter index="2" type="Function" optional="false"/>
<parameter index="3" type="Boolean" optional="true"/>
</method>
<method name="addEventListener" declaredBy="models.bo::Contact" returnType="void">
<parameter index="1" type="String" optional="false"/>
<parameter index="2" type="Function" optional="false"/>
<parameter index="3" type="Boolean" optional="true"/>
<parameter index="4" type="int" optional="true"/>
<parameter index="5" type="Boolean" optional="true"/>
</method>
<accessor name="contactId" access="readwrite" type="int" declaredBy="models.bo::Contact">
<metadata name="Bindable">
<arg key="event" value="propertyChange"/>
</metadata>
<metadata name="Column">
<arg key="name" value="contact_id"/>
</metadata>
<metadata name="Id"/>
</accessor>
</type>