Asea:一个轻量级的AS3模块配置与加载管理库

代码已经托管到github:https://github.com/boycy815/asea

该库的设计最初是为了方便配置RSL,后来发现功能逐渐与Spring接近,所以干脆对功能重新规划了一次取名为Asea,在AS3上实现了基本的IOC功能。

以下内容让您学会如何使用Asea。

一. Hello World

package
{
    import com.alibado.asea.*;

    import flash.display.Sprite;

    public class AseaTest extends Sprite
    {
        public function AseaTest()
        {
            //定义配置xml
            var xml:XML = new XML(<asea><trace value="string/hello world"  /></asea>);

            //获取根节点处理器
            var asea:EaDrop = EaConfig.getDrop("asea");

            //定义上下文对象
            var context:Object = {};

            //执行
            asea.process(xml, [context]);
        }
    }

}

除非您打算扩展它,否则使用Asea的仅需要四步。

配置xml中定义了您要执行的命令,命令的具体语法将在下面介绍。

上下文对象是xml命令执行的数据环境,换句话说,您可以在xml命令中从上下文对象中获取数据和写入数据,您可以尝试把上下文对象另外保存起来,这样您就可以通过它获取到处理后的结果了。这里提醒一点,如果您的上下文对象并非动态对象,那么当您尝试在xml上写入上下文环境中不存在的属性时,系统将报错(ReferenceError),当然一般来说您没有必要这么做。

根节点处理器就是一个大烤箱,您把执行命令和上下文数据交给它,它帮您处理。根节点处理器从EaConfig中获取,一般来说获取名字是“asea”的根节点处理器是不会错的,除非您非常确切得知道您的根节点是什么标签。另外方法process的第三个参数是成功后的回调,其定义应该是function(result:* = null):void,result处理后的结果,如果您的根节点是“asea”,那么result肯定是null,该回调存在的意义在于,考虑您的xml可能是异步处理的,比如在xml中加载个数据什么的。。process的第四个参数是出错后的回调,定义是function(errorCode:int, message:String, target:String, xml:XML):void。

对了,您可能还注意到process的第二个参数并非直接是context对象,而是一个只有context一个元素的数组。这个问题涉及到作用域链,作用域链的作用将在后面讲到。我知道这样看起来不太友好,希望哪个好人能帮它再封装一层吧。

二. 标签处理器

Asea目前提供的标签有:asea,class,get,if,lib,method,new,selector,trace,with,bean。

您可以在EaConfig这个类的drops属性中找到这些定义,drops是个包含所有标签处理器的数组,如果您定义了自己的标签处理器,可以push到这个数组中即可生效。

所有的标签处理器都继承EaDrop这个类,您只需覆盖onProcess方法和get name方法即可定义自己的标签处理器。另外提醒一点,标签处理器是无状态的,全局唯一实例,所以如果您的变量不是定义在方法体内,就要小心处理了。

这里贴出了最简单的标签处理器

package com.alibado.asea.drops
{
    import com.alibado.asea.EaDrop;

    public class EaGet extends EaDrop
    {

        override public function get name():String
        {
            return "get";
        }

        /**
         * example:
         * <get id="myPen" value="pen" >
         */
        override protected function onProcess(dom:XML, value:*, contexts:Array, onComplete:Function, onError:Function = null):void
        {
            onComplete(value);
        }
    }

}

在EaGet中覆盖了public function get name():String,需要在该方法中返回该标签处理器的要处理的标签名。

另外还要覆盖protected function onProcess(dom:XML, value:*, contexts:Array, onComplete:Function, onError:Function = null):void,该方法的第一个参数是处理的xml,系统会保证该xml的根节点名就是get name中指定的名字;第二个参数value是在标签中的value属性在上下文环境中查询到的数据,如果您不想知道查询的结果想自己处理value属性,那么您就去访问xml.@value吧;contexts是上下文环境;onComplete是处理成功后的回调,如果您的标签处理器会产生结果,那么就往onComplete里面传递结果吧,如果您的处理不产生结果,那也要调用一次onComplete,因为整个处理链是依赖onComplete进行的,如果您的标签有id属性且您传递了结果,那么系统会自动把您的结果保存在id属性指定的地方,onError是处理出错后的回调,定义已经在上文中提到过了。除非是特别严重的错误,否则我们不建议因为出错而不调用onComplete。因为如果您不调用onComplete,系统会认为您的标签尚未处理完成,整个处理过程将无法继续。

三. 上下文环境的操作

上下文环境是个数组,其中下标为0的对象为“当前上下文”,数组末尾的对象为“根上下文”,一般来说“根上下文”是我们人为提供的,就像Hello World程序里定义的那个上下文对象。其他上下文对象则是在运行xml时产生的,至于为什么产生,什么时候会产生,这些问题在下文中介绍具体介绍标签时讲解。

有了上下文环境,我们就需要在上下文环境总读取和写入数据,通过标签的value属性可从上下文环境中读取数据。

读取的量可分常量与变量,常量分为string,number,boolean三种类型,例如"string/hello world"是字符串常量,"number/110"是数字常量,"boolean/true"是布尔型常量,其余写法都算作变量。

@root是一个关键字,代表根上下文,我们可以以@root.attr的方式访问根上下文的属性,也可以@root.attr.attr2的方式进一步访问。@this也是一个关键字,代表当前上下文环境。如果不使用关键字,比如myBall.x这样的方式,则系统首先搜索当前上下文环境是否有myBall属性,若是没有,则再向上一级搜索,直到搜索到根上下文环境,这一点类似与JS的属性访问规则。

通过id属性可保存标签执行的结果,若是id为myBall.x,那么首先系统将在上下文环境中由内向外搜索myBall属性,找到myBall对象后往其内设置x属性。若是myBall属性不存在,则将会在其当前上下文对象中建立myBall属性,并且设置x属性。同样的myBall.positon.x的话,若是myBall不存在,则建立之,而后建立positon,最后设置x。id的设置同样支持@root和@this,若是id直接等于@this或者@root,那么你就能直接把上下文对象给覆盖了。。这相当危险但是有用。

四. 标签详解

asea:所有标签中最重要的一个,该标签什么属性也不支持,但是它却是其他标签正常运行的容器,它一般作为根节点或者被其他标签处理器作为父类;

bean:

/**
         * example:
         * <bean id="myBean">
         *     <new id="newObj" value="Pic">
         *         <get value="box"   />
         *         <get value="number/400"   />
         *         <get value="number/300"   />
         *         <get value="string/this is my title"   />
         *     </new>
         *     <get id="newObj.a" value="box"   />
         *     <get id="newObj.b" value="number/400"   />
         *     <get id="newObj.c" value="number/300"   />
         *     <get id="newObj.d" value="string/this is my title"   />
         * </bean>
         */

定义一个对象的定义(并不直接执行内部代码),内部第一个标签必须是new标签,new标签执行前当前上下文对象是个空对象,new标签之后当前上下文对象变成new出来的对象。而后的代码可对new出来的对象设置属性等操作。。。bean标签的执行结果是一个对象定义,当每次被访问时,都会执行一次对应的bean标签内部的代码并得到构造出来的内容。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 处理器
, 标签
, 属性
, 环境
上下文
,以便于您获取更多的相关知识。

时间: 2025-01-21 16:40:45

Asea:一个轻量级的AS3模块配置与加载管理库的相关文章

JavaScript 模块的循环加载实现方法_javascript技巧

"循环加载"(circular dependency)指的是,a脚本的执行依赖b脚本,而b脚本的执行又依赖a脚本. // a.js var b = require('b'); // b.js var a = require('a'); 通常,"循环加载"表示存在强耦合,如果处理不好,还可能导致递归加载,使得程序无法执行,因此应该避免出现. 但是实际上,这是很难避免的,尤其是依赖关系复杂的大项目,很容易出现a依赖b,b依赖c,c又依赖a这样的情况.这意味着,模块加载机

JavaScript 模块的循环加载

"循环加载"(circular dependency)指的是,a脚本的执行依赖b脚本,而b脚本的执行又依赖a脚本. // a.js var b = require('b'); // b.js var a = require('a'); 通常,"循环加载"表示存在强耦合,如果处理不好,还可能导致递归加载,使得程序无法执行,因此应该避免出现. 但是实际上,这是很难避免的,尤其是依赖关系复杂的大项目,很容易出现a依赖b,b依赖c,c又依赖a这样的情况.这意味着,模块加载机

seajs学习之模块的依赖加载及模块API的导出_Seajs

前言 SeaJS非常强大,SeaJS可以加载任意 JavaScript 模块和css模块样式,SeaJS会保证你在使用一个模块时,已经将所依赖的其他模块载入到脚本运行环境中. 通过参照上文的demo,我们结合源码分析在简单的API调用的背后,到底使用了什么技巧来实现各个模块的依赖加载以及模块API的导出. 模块类和状态类 首先定义了一个Module类,对应与一个模块 function Module(uri, deps) { this.uri = uri this.dependencies = d

tomcat集群-nginx 反向代理三个本地tomcat 负载均衡配置 无法加载js css 图片等 也不报错

问题描述 nginx 反向代理三个本地tomcat 负载均衡配置 无法加载js css 图片等 也不报错 打开速度非常慢,到最后js css无法加载是什么问题 我的项目是ssh+jquery+easyui的 单独访问tomcat完全正常 访问nginx就这样了 .求大神指点啊 访问webapp根目录是可以的 我的页面都是在web-inf目录下的貌似不行 nginx配置如下: #user nobody; worker_processes 1; #error_log logs/error.log;

初学者-想新建一个空白应用程序,可是无法加载设计器,

问题描述 想新建一个空白应用程序,可是无法加载设计器, 我是一个C# 的初学者,在创建一个"window 应用商店"-"空白应用程序"后无法加载设计器,说发生了未经处理的错误?哪位大神能帮我解决呀!界面显示如下: 发生了未经处理的错误 单击以加载设计器 System.NullReferenceException Object reference not set to an instance of an object. 在 Microsoft.Expression.D

relativelayout-定义一个类继承RelativeLayout在用inflater加载布局文件时为什么找不到?

问题描述 定义一个类继承RelativeLayout在用inflater加载布局文件时为什么找不到? 解决方案 http://www.oschina.net/question/657381_122348 解决方案二: 是不是import的R路径不对啊

在android中使用webview加载完一个网页后,如何知道一共加载了多少资源?

问题描述 在android中使用webview加载完一个网页后,如何知道一共加载了多少资源? RT,现在有一个需求要知道用webview加载完任意一个网页后一共有多少个资源,现在问题是不知道什么时候网页完全加载完,因为当webclient回调onPageFinished()之后,还是会继续回调onLoadResource()来加载资源,求给个思路 解决方案 用抓包工具(wireshark)即可查看 解决方案二: 可以在底层抓包实现哦... 解决方案三: 多少资源? 包括多少个图片js 吗 ? 分

tomcat-Tomcat加载配置时加载到jdbc就停止加载

问题描述 Tomcat加载配置时加载到jdbc就停止加载 信息: Initializing Spring root WebApplicationContext 2015-11-18 19:05:51,346 [Thread-1] INFO [org.springframework.web.context.ContextLoader] - Root WebApplicationContext: initialization started 2015-11-18 19:05:51,664 [Thre

nginx+新模块-Nginx 如何加载一个新的模块 而不是基于http模块的?

问题描述 Nginx 如何加载一个新的模块 而不是基于http模块的? 想用Nginx 做一个服务器,但是又不是基于http模块的,而是想自己建一个模块,请问该如何修改那些configure.makefile,希望各位能指点一个,深表感谢. 解决方案 希望各位懂的帮忙回答一下,谢谢 解决方案二: 希望各位懂的帮忙回答一下,谢谢