Реагировать на изменение статического свойства

Я переписываю средство визуализации элементов MXML в чистом AS. Проблема, которую я не могу решить, заключается в том, как заставить каждый модуль визуализации элементов реагировать на изменение статического свойства в классе средства визуализации элементов. В версии MXML у меня настроена следующая привязка в средстве визуализации элементов:

instanceProperty={callInstanceFunction(ItemRenderer.staticProperty)}

Каким будет эквивалентный способ настроить это в AS (я полагаю, с помощью BindingUtils)?

ОБНОВЛЕНИЕ:
Итак, я подумал, что следующее не работает, но похоже, что Flex подавляет ошибки, возникающие в instanceFunction, создавая впечатление, что сама привязка плохая.

BindingUtils.bindSetter(instanceFunction, ItemRenderer, "staticProperty");

Однако при вызове instanceFunction все уже инициализированные переменные в данном экземпляре имеют значение null, что и было причиной ошибок, упомянутых выше. Есть идеи, почему это так?


person Stiggler    schedule 01.06.2009    source источник


Ответы (5)


У вас есть 2 варианта, о которых я знаю:

Вариант 1. Вы можете изучить код, созданный компилятором flex на основе вашего MXML, чтобы увидеть, как он обрабатывает привязку к статическим свойствам. Существует директива компилятора под названием -keep-generated-actionscript, которая заставит сгенерированные файлы остаться. Их изучение может дать вам представление о том, что происходит. Этот параметр будет включать создание экземпляров объектов Binding и StaticPropertyWatcher.

Вариант 2 Существует объект staticEventDispatcher, который добавляется во время сборки к классам, содержащим статические переменные, см. этот пост http://thecomcor.blogspot.com/2008/07/adobe-flex-undocumented-buildin.html. Согласно сообщению, этот объект добавляется только на основе наличия статических переменных, а не функций получения.

Пример варианта 2. Допустим, у нас есть класс с именем MyClassContainingStaticVariable со статической переменной с именем MyStaticVariable и другой переменной someobject.somearrayproperty, которую мы хотим обновить. всякий раз, когда изменяется MyStaticVariable.

Class(MyClassContainingStaticVariable).staticEventDispatcher.addEventListener(
PropertyChangeEvent.PROPERTY_CHANGE,
function(event:PropertyChangeEvent):void
{
    if(event.property == "MyStaticVariable")
    {
        someobject.somearrayproperty = event.newValue as Array;
    }
});
person bingles    schedule 07.03.2012
comment
Ницца! Flash Builder даже не выполняет автозаполнение для Class::staticEventDispatcher(), но работает - person sydd; 10.04.2012
comment
Да, судя по упомянутому сообщению, я думаю, что он добавляется во время сборки, поэтому фактически недоступен для автоматического завершения во время кодирования. - person bingles; 28.04.2012
comment
@bingles Очень интересный материал! Конечно, я уже давно перешел, но хорошая работа, раскопать это. - person Stiggler; 05.12.2014
comment
К сожалению, BindingUtils не справится с этим за вас (я полагаю, что должен, абстрагирование процедуры привязки является его обязанностью). Поэтому мы должны использовать этот обходной путь staticEventDispatcher. - person user1875642; 03.11.2015

Я думаю, вам нужно отреагировать на событие «PropertyChanged».

person CookieOfFortune    schedule 01.06.2009
comment
Не могли бы вы немного уточнить? Как/когда отправляется это событие? - person Stiggler; 02.06.2009

Если вы собираетесь это сделать, используйте синглтон вместо статического. Я не думаю, что это будет работать на статике. (Если вам вообще нужно сделать это таким образом, вероятно, есть несколько способов, которыми вы могли бы изменить это, что было бы лучше).

var instance:ItemRenderer = ItemRenderer.getInstance();
BindingUtils.bindProperty(this, "myProperty", instance, "theirProperty"); 
person Sean Clark Hess    schedule 01.06.2009
comment
Извините, но я не ищу другого подхода, потому что этот работает в MXML. Меня интересует работа, которая происходит за кулисами. - person Stiggler; 02.06.2009
comment
Ну, привязка устанавливает прослушиватели событий для свойств. Вы не можете прослушивать объект класса, потому что это не EventDispatcher. Вы могли бы сделать это, если бы ваш класс расширил EventDispatcher и вы использовали метод singleton. Какими бы плохими ни были синглтоны, статические классы - худшие. Это может работать в MXML, но почти наверняка не привязано. Он может просто найти значение один раз и никогда не обновляться после этого. - person Sean Clark Hess; 04.06.2009
comment
Я ценю ваше время, но, похоже, мы не на одной волне. Прежде всего, я хочу сделать это для ItemRenderer, подразумевая, что класс будет иметь несколько экземпляров, что немедленно исключает любое использование синглтона, к лучшему или к худшему. Во-вторых, разрешена привязка к статическим свойствам, если это не статический геттер/сеттер. Привязка, которую я настроил в MXML, работает не один раз, а в 100% случаев. - person Stiggler; 05.06.2009

Повозившись с этим некоторое время, я пришел к выводу, что в настоящее время это невозможно в ActionScript, даже в bindSetter. Судя по следующему отрывку из документации Adobe, судя по следующей выдержке из документов Adobe, существуют некоторые функции привязки данных только для MXML (хотя разве все это не скомпилировано в код AS)?

Вы не можете включать функции или элементы массива в цепочки свойств в выражение привязки данных, определенное методом bindProperty() или bindSetter(). Дополнительные сведения о цепочках свойств см. в разделе Работа с привязываемыми цепочками свойств.

Источник: http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_7.html

person Stiggler    schedule 12.08.2009

Вы можете создать класс HostProxy для вызова функции. Что-то вроде класса HostFunctionProxy, который расширяется от прокси-сервера и имеет getProperty("functionInvokeStringWithParameters"), который будет вызывать функцию удаленно с хоста и отправлять событие «change», чтобы вызвать привязку в типичном классе [Bindable("change")] Proxy.

Затем вы позволяете классу HostProxy действовать как хост и использовать это свойство для удаленного запуска вызова функции. Конечно, было бы круче иметь несколько TypeHelperUtil, позволяющих преобразовывать необработанные строковые значения в значения сериализованного типа во время выполнения для параметров метода (обычно разделенных запятыми).

Пример: напр.

 var standInHost:Object = new HostFunctionProxy(someModelClassWithMethod, "theMethodToCall(20,11)");
// With BindingUtils.....
// bind host: standInHost
// bind property: "theMethodToCall(20,11)"

Конечно, вам нужно создать такую ​​утилиту, чтобы поддерживать такую ​​функциональность, выходящую за рамки основного предписания Flex. Кажется, что многие из таких (более продвинутых) привязок Flex обычно выполняются во время компиляции, но теперь вам нужно создать код, чтобы сделать это во время выполнения в полностью кросс-платформенной манере Actionscript, не полагаясь на среду Flex.

person Glenn    schedule 14.03.2010