http://m.blog.csdn.net/blog/cceevv/8779480
在AS3 使用元数据标签最多的应该是swf标签了,如:
- [SWF(backgroundColor = 0x000000, frameRate = 24, width = 1000, height = 600)]
那么能不能自定义我们自己的标签,然后在运行时,获取那些含有自定义标签的类或者类成员,然后达到注入的目的呢?答案是肯定的,在robotleg等一些开源框架中也用到了注入。
要是有元数据标签需要在编译器的扩展参数中指定-keep-as3-metadatac参数:
- -keep-as3-metadata+=Inject,BindData
后面的Inject、BindData就是下面的例子要用的两个标签
需要注意的是这个编译参数只需要在一个运行库中指定即可,比如我们使用swc,那么编译这个swc指定了-keep-as3-metadatac参数,那么在使用swc的库的项目是不需要再指定的。在-keep-as3-metadatac参数使用“+=”是为了避免把别的参数定义覆盖掉。
比如Test1.as类使用元标签:
- package
- {
- /**
- * ...
- * @author yoyo
- */
- [Inject]
- public class Test1
- {
- [BindData(param1="abc")]
- public var s:String = 'ssss';
- public function Test1()
- {
- }
- }
- };
接下来我们做注入操作,在不需要直接引用s成员的情况下,根据BindDta标签,修改这个成员变量的值:
- package
- {
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.utils.describeType;
- import flash.xml.XMLNode;
- /**
- * ...
- * @author yoyo
- */
- public class Main extends Sprite
- {
- public function Main():void
- {
- if (stage)
- init();
- else
- addEventListener(Event.ADDED_TO_STAGE, init);
- }
- private function init(e:Event = null):void
- {
- removeEventListener(Event.ADDED_TO_STAGE, init);
- // describeType方法返回的信息类似下面的xml
- /**
- <type name="Test1" base="Object" isDynamic="false" isFinal="false" isStatic="false">
- <extendsClass type="Object"/>
- <variable name="s" type="String">
- <metadata name="BindData">
- <arg key="param1" value="abc"/>
- </metadata>
- <metadata name="__go_to_definition_help">
- <arg key="pos" value="131"/>
- </metadata>
- </variable>
- <metadata name="Inject"/>
- <metadata name="__go_to_ctor_definition_help">
- <arg key="pos" value="173"/>
- </metadata>
- <metadata name="__go_to_definition_help">
- <arg key="pos" value="79"/>
- </metadata>
- </type>
- */
- var t:Test1 = new Test1();
- initMeta(t);
- trace(t.s);//打印修改后的值
- }
- /**
- * 开始对这个对象进行注入
- * @param obj
- */
- private function initMeta(obj:*):void
- {
- var xml:XML = describeType(obj);
- var typeName:String = xml.@name;
- initClassMeta(obj,typeName,xml);
- for (var i:int = 0, len:int = xml.variable.length(); i < len;i++)
- {
- var variables:XML = xml.variable[i];
- initVariableMeta(obj,typeName,variables);
- }
- }
- /**
- * 获取含有自定义标签的类对象
- * @param xml
- */
- private function initClassMeta(obj:*,typeName:String,xml:XML):void
- {
- for (var i:int = 0, len:int = xml.metadata.length(); i < len;i++)
- {
- var mata:XML = xml.metadata[i];
- var metaName:String = mata.@name;
- switch (metaName)
- {
- case 'Inject':
- trace(typeName + ',Inject:' + metaName);
- break;
- }
- }
- }
- /**
- * 获取含有自定义标签的成员变量
- * @param xml
- */
- private function initVariableMeta(obj:*,typeName:String,xml:XML):void
- {
- var name:String = xml.@name;
- var type:String = xml.@type;
- for (var i:int = 0, len:int = xml.metadata.length(); i < len;i++)
- {
- var mata:XML = xml.metadata[i];
- var metaName:String = mata.@name;
- switch (metaName)
- {
- case 'BindData':
- trace(typeName + ',BindData:' + metaName + '(' + mata.arg[0].@value + ')');
- obj[name] = 'inject';//修改这个成员变量的值
- break;
- }
- }
- }
- }
- }
输出如下:
完整代码下载:metaDataTest.zip
作者:YoYo,原文地址:http://yoyo.play175.com/p/186.html