Динамический доступ к свойствам в пользовательских пространствах имен - PullRequest
2 голосов
/ 27 августа 2011

Учитывая это:

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: свойство foo :: bar не найдено в MyClass и отсутствует значение по умолчанию.

При дальнейшей проверкеВ пространстве имен foo я вижу (в отладчике), что URI имеет формат {пакет}: {тип} / {имя}.Если я попытаюсь повторить это, выполнив следующее:

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 Ответ

1 голос
/ 04 сентября 2011

Редактировать 2: Хорошо, проблема в том, что когда вы создаете пространство имен, компилятор создает его с внутренним пакетом флага, или у вас нет способа создать в as3 пространство имен с другим флагом доступа (public, protected, ...)

Таким образом, если ваше пространство имен объявлено общедоступным, вы можете получить его с помощью функции 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");

Edit: Хорошо, я не прочитал, что у вас есть проблема с динамическим именем пространства имен, а не с динамическим именем свойства: Таким образом, вы можете получить доступ к созданному вами пространству имен путем статического обращения к имени вашего пространства имен из класса, в котором оно определено:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...