Объекты с поддержкой динамических имён свойств с использованием пользовательских пространств имён

Flex cookbook entry: How to and where store dynamic properties in custom namespaces.

Мне очень нравится в ActionScript 3 тесная интеграция с XML и популяризация пространств имён. Для поддержки свойств в различных пространствах имён даже создан отдельный класс – QName, объединяющий в себе указатель пространства имён и локальное имя. Но, получается что, для использования пространств имён отличных от базовых(AS3 и с пустым указателем) разработчик должен сам реализовать поддержку этих пространств имён, заранее объявив члены класса.

Динамические члены класса в пользовательских пространствах имён не поддерживаются, кроме XML объектов. Чтоб включить такую поддержку необходимо расширить класс flash.utils.Proxy и самому её реализовать. Это и было сделано в классах описываемых в этом посте – они разрешают добавлять в себя динамические члены класса в любых пространствах имён(кроме flash_proxy, в сочетании с зарезервированными локальными именами, методы которых уже реализованы).

Итак, есть 2 коллекции и 2 обёртки для них в виде классов расширяющих flash.utils.Proxy. Первый класс QNameCollection поддерживает пространства имён в именах динамических свойств, а XMLNameCollection дополнительно поддерживает атрибуты. Следует заметить, что QNameCollection игнорирует указатель атрибута в QName и если попробовать добавить атрибут, он просто добавит свойство под этим именем, при этом значение указателя теряется.

Коллекции используют методы аналогичные методам flash.utils.Proxy для доступа к элементам

  • callProperty – вызвать метод с указанным именем
  • getProperty – получить значение свойства по имени
  • hasProperty – проверить наличие свойства по имени
  • deleteProperty – удалить свойство по имени
  • setProperty – установить свойство по имени

Все эти методы принимают выборки с не указанными(NULL в QName.uri означает любое пространство имён, а "*" – любое локальное имя) пространством имён или локальным именем.

И дополнительно методы:

  • getPropertyList – список имён доступных свойств
  • getPropertyNamespaceList – список использованных пространств имён
  • forEach – перебор всех свойств объекта. Используется функция обратного вызова, принимает в качестве аргументов значение свойства и имя свойства

В конструкторе обе коллекции принимают атрибут "liveNameList", указывающий на необходимость содержать постоянно обновляемый список имён свойств, который используется для перебора свойств. Если эта опция выключена, то список имён создаётся по необходимости, к примеру, непосредственно перед перебором в цыкле.

А обё обёртки просто позволяют использовать привычный синтаксис

  1. var ns1:Namespace = new Namespace('urn:some-uri-1');
  2. var ns2:Namespace = new Namespace('urn:some-uri-2');
  3. var ns3:Namespace = new Namespace('urn:some-uri-3');
  4. var qNames:QNameDynamicCollection = new QNameDynamicCollection();
  5. qNames.ns1::property1 = 'property1';
  6. qNames.ns1::property2 = 'property2';
  7. qNames.ns2::property1 = 'property3';
  8. qNames.ns2::property2 = 'property4';
  9. qNames.ns3::property1 = 'property5';
  10. qNames.ns3::property2 = 'property6';
  11. trace(qNames.*::*); // property1,property2,property3,property4,property5,property6
  12. trace(qNames.ns2::*); // property3,property4
  13. delete qNames.ns2::*;
  14. trace(qNames.ns2::*.length); // 0
  15. var xmlNames:XMLNameDynamicCollection = new XMLNameDynamicCollection();
  16. xmlNames.@ns1::attribute1 = 'attribute1';
  17. xmlNames.@ns1::attribute2 = 'attribute2';
  18. xmlNames.@ns2::attribute1 = 'attribute3';
  19. xmlNames.@ns2::attribute2 = 'attribute4';
  20. xmlNames.@ns3::attribute1 = 'attribute5';
  21. xmlNames.@ns3::attribute2 = 'attribute6';
  22. xmlNames.ns1::property1 = 'property1';
  23. xmlNames.ns1::property2 = 'property2';
  24. xmlNames.ns2::property1 = 'property3';
  25. xmlNames.ns2::property2 = 'property4';
  26. xmlNames.ns3::property1 = 'property5';
  27. xmlNames.ns3::property2 = 'property6';
  28. trace(xmlNames.*::*); // property1,property2,property3,property4,property5,property6
  29. trace(xmlNames.@*::*); // attribute1,attribute2,attribute3,attribute4,attribute5,attribute6
  30. trace(xmlNames.@ns2::*.length); // 2
  31. delete xmlNames.@*::*;
  32. trace(xmlNames.@*::*.length); // 0

Особенности работы с этими объектами

  • сollection.* – любой запрос по выборке возвращает массив, поэтому чтоб узнать наличие свойств в пространстве имён надо использовать свойство Array.length, как и в случае XML узлов – XMLList.length().
  • var value:Array = сollection.* – вернёт только свойства находящиеся в базовом пространстве имён, чтоб получить все свойства во всех пространствах имён используйте collection.*::*, collection.@*::* для атрибутов.
  • сollection.ns::* = value – не создаст новых свойств, но существующим свойствам присвоит новое значение.
  • Второй аргумент в конструкторе обёртки "autoParseStringNames", указывает на возможность автоматической конвертации строк с "::" в экземпляры QName. Я добавил эту опцию из-за глюка в интерфейсе flash.utils.Proxy – если использовать цыкл for..in, то для получения имени свойства используется метод Proxy.nextName, который может вернуть только строку.

Скачать весь пакет одним файлом: QName & XMLName collections (40)

Метки: , , , , ,

Добавить комментарий

Вы должны авторизоваться для отправки комментария.