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", указывающий на необходимость содержать постоянно обновляемый список имён свойств, который используется для перебора свойств. Если эта опция выключена, то список имён создаётся по необходимости, к примеру, непосредственно перед перебором в цыкле.
А обё обёртки просто позволяют использовать привычный синтаксис
var ns1:Namespace = new Namespace('urn:some-uri-1'); var ns2:Namespace = new Namespace('urn:some-uri-2'); var ns3:Namespace = new Namespace('urn:some-uri-3'); var qNames:QNameDynamicCollection = new QNameDynamicCollection(); qNames.ns1::property1 = 'property1'; qNames.ns1::property2 = 'property2'; qNames.ns2::property1 = 'property3'; qNames.ns2::property2 = 'property4'; qNames.ns3::property1 = 'property5'; qNames.ns3::property2 = 'property6'; trace(qNames.*::*); // property1,property2,property3,property4,property5,property6 trace(qNames.ns2::*); // property3,property4 delete qNames.ns2::*; trace(qNames.ns2::*.length); // 0 var xmlNames:XMLNameDynamicCollection = new XMLNameDynamicCollection(); xmlNames.@ns1::attribute1 = 'attribute1'; xmlNames.@ns1::attribute2 = 'attribute2'; xmlNames.@ns2::attribute1 = 'attribute3'; xmlNames.@ns2::attribute2 = 'attribute4'; xmlNames.@ns3::attribute1 = 'attribute5'; xmlNames.@ns3::attribute2 = 'attribute6'; xmlNames.ns1::property1 = 'property1'; xmlNames.ns1::property2 = 'property2'; xmlNames.ns2::property1 = 'property3'; xmlNames.ns2::property2 = 'property4'; xmlNames.ns3::property1 = 'property5'; xmlNames.ns3::property2 = 'property6'; trace(xmlNames.*::*); // property1,property2,property3,property4,property5,property6 trace(xmlNames.@*::*); // attribute1,attribute2,attribute3,attribute4,attribute5,attribute6 trace(xmlNames.@ns2::*.length); // 2 delete xmlNames.@*::*; 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)
Метки: dynamic, flash.utils.Proxy, name, property, QName, XML