守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 783|回复: 0

[AIR技术] AS3使用自定义元数据标记,类似C#的类属性、成员属性

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51840
    钢镚
    1422

    开源英雄守望者

    发表于 2015-1-9 11:13:45 | 显示全部楼层 |阅读模式
    在AS3 使用元数据标签最多的应该是swf标签了,如:
    1. [SWF(backgroundColor = 0x000000, frameRate = 24, width = 1000, height = 600)]
    复制代码

    那么能不能自定义我们自己的标签,然后在运行时,获取那些含有自定义标签的类或者类成员,然后达到注入的目的呢?答案是肯定的,在robotleg等一些开源框架中也用到了注入。

    要是有元数据标签需要在编译器的扩展参数中指定-keep-as3-metadatac参数:


    1. <font color="rgb(34, 34, 34)">-keep-as3-metadata+=Inject,BindData </font>
    复制代码
    后面的Inject、BindData就是下面的例子要用的两个标签需要注意的是这个编译参数只需要在一个运行库中指定即可,比如我们使用swc,那么编译这个swc指定了-keep-as3-metadatac参数,那么在使用swc的库的项目是不需要再指定的。在-keep-as3-metadatac参数使用“+=”是为了避免把别的参数定义覆盖掉。比如Test1.as类使用元标签:
    1. package
    2. {
    3.     /**
    4.      * ...
    5.      * @author yoyo
    6.      */
    7.     [Inject]      
    8.     public class Test1
    9.     {
    10.         [BindData(param1="abc")]
    11.         public var s:String = 'ssss';
    12.          
    13.         public function Test1()
    14.         {
    15.         }
    16.      
    17.     }

    18. };
    复制代码
    接下来我们做注入操作,在不需要直接引用s成员的情况下,根据BindDta标签,修改这个成员变量的值:
    1. package
    2. {
    3.     import flash.display.Sprite;
    4.     import flash.events.Event;
    5.     import flash.utils.describeType;
    6.     import flash.xml.XMLNode;
    7.      
    8.     /**
    9.      * ...
    10.      * @author yoyo
    11.      */
    12.     public class Main extends Sprite
    13.     {
    14.          
    15.         public function Main():void
    16.         {
    17.             if (stage)
    18.                 init();
    19.             else
    20.                 addEventListener(Event.ADDED_TO_STAGE, init);
    21.         }
    22.          
    23.         private function init(e:Event = null):void
    24.         {
    25.             removeEventListener(Event.ADDED_TO_STAGE, init);
    26.             // describeType方法返回的信息类似下面的xml
    27.             /**
    28.                <type name="Test1" base="Object" isDynamic="false" isFinal="false" isStatic="false">
    29.                <extendsClass type="Object"/>
    30.                <variable name="s" type="String">
    31.                <metadata name="BindData">
    32.                <arg key="param1" value="abc"/>
    33.                </metadata>
    34.                <metadata name="__go_to_definition_help">
    35.                <arg key="pos" value="131"/>
    36.                </metadata>
    37.                </variable>
    38.                <metadata name="Inject"/>
    39.                <metadata name="__go_to_ctor_definition_help">
    40.                <arg key="pos" value="173"/>
    41.                </metadata>
    42.                <metadata name="__go_to_definition_help">
    43.                <arg key="pos" value="79"/>
    44.                </metadata>
    45.                </type>
    46.             
    47.              */
    48.             
    49.             var t:Test1 = new Test1();   
    50.             
    51.             initMeta(t);
    52.             
    53.             trace(t.s);//打印修改后的值
    54.         }
    55.          
    56.         /**
    57.          * 开始对这个对象进行注入
    58.          * @param   obj
    59.          */
    60.         private function initMeta(obj:*):void
    61.         {
    62.             var xml:XML = describeType(obj);
    63.             
    64.             var typeName:String = xml.@name;
    65.                         
    66.             initClassMeta(obj,typeName,xml);
    67.             
    68.             for (var i:int = 0, len:int = xml.variable.length(); i < len;i++)
    69.             {
    70.                 var variables:XML = xml.variable[i];
    71.             
    72.                 initVariableMeta(obj,typeName,variables);
    73.             }
    74.         }
    75.          
    76.         /**
    77.          * 获取含有自定义标签的类对象
    78.          * @param   xml
    79.          */
    80.         private function initClassMeta(obj:*,typeName:String,xml:XML):void
    81.         {
    82.             for (var i:int = 0, len:int = xml.metadata.length(); i < len;i++)
    83.             {
    84.                 var mata:XML = xml.metadata[i];
    85.                 var metaName:String = mata.@name;
    86.                 switch (metaName)
    87.                 {
    88.                     case 'Inject':
    89.                         trace(typeName + ',Inject:' + metaName);
    90.                         break;
    91.                 }
    92.             }
    93.         }
    94.          
    95.         /**
    96.          * 获取含有自定义标签的成员变量
    97.          * @param   xml
    98.          */
    99.         private function initVariableMeta(obj:*,typeName:String,xml:XML):void
    100.         {
    101.             var name:String = xml.@name;
    102.             var type:String = xml.@type;
    103.             for (var i:int = 0, len:int = xml.metadata.length(); i < len;i++)
    104.             {
    105.                 var mata:XML = xml.metadata[i];
    106.                 var metaName:String = mata.@name;
    107.                 switch (metaName)
    108.                 {
    109.                     case 'BindData':
    110.                         trace(typeName + ',BindData:' + metaName + '(' + mata.arg[0].@value + ')');
    111.                         obj[name] = 'inject';//修改这个成员变量的值
    112.                         break;
    113.                 }
    114.             }
    115.         }
    116.      
    117.     }
    118. }
    复制代码
    输出如下:







    完整代码下载:metaDataTest.zip






    作者:YoYo,原文地址:http://yoyo.play175.com/p/186.html



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2020-6-5 00:57 , Processed in 0.043672 second(s), 32 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表