动态访问自定义命名空间中的属性

时间:2011-08-26 23:58:06

标签: flash actionscript-3

鉴于此:

public namespace foo;
foo var bar:String = "baz";

我们可以像这样访问属性“bar”:

var ns:Namespace = foo;
trace(ns::["bar"]);

然而,这不起作用:

var ns:Namespace = new Namespace("foo");
trace(ns::["bar"]);

它给了我以下错误:

  

ReferenceError:错误#1069:在MyClass上找不到属性foo :: bar,并且没有默认值。

在进一步检查foo命名空间时,我可以看到(在调试器中)URI的格式为{package}:{type} / {name}。如果我尝试通过执行以下操作来复制它:

var ns:Namespace = new Namespace(getQualifiedClassName(this).replace("::", ":") + "/foo");
trace(ns::["bar"]);

(击鼓声)

仍然没有骰子。

另外,我没有运气就尝试了以下组合:

var ns:Namespace = new Namespace(null, getQualifiedClassName(this).replace("::", ":") + "/foo");
var ns:Namespace = new Namespace("", getQualifiedClassName(this).replace("::", ":") + "/foo");

有谁知道是否可以访问这样的命名空间成员?我没有编译时访问命名空间,但我可以在运行时动态查找它的uri(和前缀)。

1 个答案:

答案 0 :(得分:1)

编辑2: 好的问题是,当您创建命名空间时,编译器使用标志包内部创建它,或者您无法在as3中创建具有不同访问标志的命名空间(public,protected,...)

因此,如果您的命名空间被声明为public,则可以使用函数getDefinition来获取它。

这是一个函数示例,它解析你的uri,并在文件或类中声明它时返回你的命名空间

package XXX {
 public namespace foo;
}

package YYY {
 class XXX {
  public namespace foo2;
 }
}

这是一个从uri

中为您提供命名空间的函数示例
    public function getNamespaceFromURI(uri:String, domain:ApplicationDomain = null):Namespace {
        if(domain == null) domain = ApplicationDomain.currentDomain;

        var tmp:Array = uri.split("/");
        var ns:Namespace = null;
        var pkg:String = tmp[0].replace(":", ".");
        if(tmp.length == 1) {
            // namespace declared in a file
            ns = domain.getDefinition(pkg) as Namespace;
        } else {
            // namespace inside a class
            var cls:Class = domain.getDefinition(pkg) as Class;
            if(cls) {
                ns = cls[tmp[1]] as Namespace;
            }
        }
        return ns;
    }

用法:

var ns:namespace = getNamespaceFromURI("YYY:foo");
// or
var ns:namespace = getNamespaceFromURI("YYY:XXX/foo2");

修改 好的,我想念你有一个动态名称空间名称而不是动态属性名称的问题: 因此,您可以通过从定义它的类中对命名空间名称进行静态调用来访问您创建的命名空间:

class X {
 public namespace foo;
}  

var ns:Namespace=X['foo'];

所以你的例子是:

public namespace foo;
foo var bar:String = "baz";

var ns:Namespace=MyClass['foo'];
trace(ns::['bar'])

我更新了wonderfl示例:http://wonderfl.net/c/7M9O

您可以使用自定义命名空间和动态名称创建新的QName,然后使用此[myQName]访问该属性:

var ns:Namespace=foo;
var qn:QName=new QName(foo, 'bar');
trace(this[qn]);

这是关于wonderfl的实例:http://wonderfl.net/c/7M9O