Темой статьи стала проблема, с которой я столкнулся, разрабатывая некоторый продукт на Flex'е.
Начнем. Как можно привязать XML данные к некоторому значению визуального компонента... В общем-то не сложно:
и MXML'ом привязуем его к компоненту:
Когда изменяется
Припустим компонент
которым передается некоторая выборка из
Итак постает вопрос - как сделать так чтобы
Результат -
последующие изменения в
Поковырявшись пару часов в том что генерирует Flex Builder выяснилось следующее
(привожу в пример код, в ходе буду объяснять):
Также можно связать данные не только с XML а и с другими типами данных
используя следующие классы с Flex SDK пакета
Надеюсь, данная публикация поможет людям, которые столкнулись с этой проблемой.
Начнем. Как можно привязать XML данные к некоторому значению визуального компонента... В общем-то не сложно:
[Bindable]<br/>
private var some_xml_data: XML;
и MXML'ом привязуем его к компоненту:
<some_component some_property="{some_xml_data}" />
Когда изменяется
some_xml_data
то some_property
в some_component
'а тоже меняется... Припустим компонент
some_component
создает динамически еще некоторые компоненты,которым передается некоторая выборка из
some_property
some_component
'а:var dynamic_component: DynamicComponent = new DynamicComponent();<br/>
dynamic_component.some_other_property = some_property.item.(@name=='name')[0];<br/>
Итак постает вопрос - как сделать так чтобы
data binding
в dynamic_component
тоже работала?BindingUtils.bindProperty(dynamic_component, 'some_other_property', some_property.item.(@name=='name'), '0');
Результат -
some_other_property
меняется только 1 раз, когда вызывается метод bindProperty
,последующие изменения в
some_xml_data
никак не влияют. В документации и гугле я ничего не нарыл…Поковырявшись пару часов в том что генерирует Flex Builder выяснилось следующее
(привожу в пример код, в ходе буду объяснять):
//импорт необходимых классов<br/>
//точного их описания не дам, так как все что я нашел, это исходники классов,<br/>
//которых нет в документации<br/>
import mx.binding.Binding;<br/>
<br/>
import mx.binding.PropertyWatcher;<br/>
import mx.binding.XMLWatcher;<br/>
<br/>
//исходное свойство<br/>
<br/>
[Bindable]<br/>
private var src_prop: XML = <br/>
<root><br/>
<br/>
<item0><br/>
<item1 name="some name" /><br/>
</item0><br/>
<br/>
</root>;<br/>
<br/>
//результирующее свойство<br/>
private var dest_prop: XML;<br/>
<br/>
//функция которая связывает dest_prop как dest_prop = src_prop..item1.@name<br/>
private function bindProp(): void {<br/>
<br/>
var binding:Binding;<br/>
//Создает объект для связывания.<br/>
// public function Binding(document:Object, srcFunc:Function,<br/>
// destFunc:Function, destString:String)<br/>
//document - это документ, который является целью всей этой работы ( не очень звучит) ).<br/>
// (в большинстве случаев это будет this)<br/>
//srcFunc - это функция, которая возвращает значение которое <br/>
// задается результирующему свойству<br/>
//destFunc - функция, которая будет принимать значения<br/>
// и назначать его результирующему свойству.<br/>
//destString - наименование результирующего свойства, которое предоставляется в виде строки <br/>
<br/>
binding = new Binding(<br/>
this,<br/>
function(): * {<br/>
return src_prop..item1.@name;<br/>
},<br/>
function(_sourceFunctionReturnValue:*):void {<br/>
dest_prop = _sourceFunctionReturnValue;<br/>
},<br/>
'dest_prop'<br/>
);<br/>
<br/>
//PropertyWatcher - нужен если заменяется значение свойства<br/>
//public function PropertyWatcher(propertyName:String,<br/>
// events:Object,<br/>
// listeners:Array,<br/>
// propertyGetter:Function = null)<br/>
//propertyName - наименование свойства для просмотра.<br/>
//events - события которые указывают что свойство изменилось <br/>
// (в данном случае это {propertyChange: true}).<br/>
//listeners - массив Binding объектов, которые слушают этот Watcher.<br/>
//propertyGetter - функция-помощник которая используется для доступа <br/>
// непубличный переменных.<br/>
var watcher: PropertyWatcher = new PropertyWatcher(<br/>
'src_prop', <br/>
{propertyChange: true},<br/>
[binding],<br/>
function(propertyName:String):* {return this[propertyName];}<br/>
);<br/>
watcher.updateParent(this);<br/>
//XMLWatcher - нужен если меняется значение какой то ветки XML'а<br/>
//addChild - добавляет watcher'a, который будет наблюдать за <br/>
// измениями внутри свойства.<br/>
watcher.addChild(new XMLWatcher('item1', [binding]));<br/>
<br/>
//исполняет присваивание dest_prop = src_prop..item1.@name<br/>
binding.execute();<br/>
}
Также можно связать данные не только с XML а и с другими типами данных
используя следующие классы с Flex SDK пакета
mx.binding
:ArrayElementWatcher<br/>
FunctionReturnWatcher<br/>
RepeaterComponentWatcher<br/>
RepeaterItemWatcher<br/>
StaticPropertyWatcher
Надеюсь, данная публикация поможет людям, которые столкнулись с этой проблемой.