views:

472

answers:

2

Hi to all, well, I have a combobox which I have bind his selectedItem property to a value object object, like this

<fx:Binding source="styles_cb.selectedItem.toString()" destination="_uniform.style"/>
<fx:Declarations>
<fx:XML id="config_xml" xmlns="" source="config.xml" />
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<mx:ComboBox x="66.15" y="63.85" editable="false" id="styles_cb" dataProvider="{config_xml.styles.style}" />

the value object is a custom class with some setters and getters, and I want to set a property based of the value of the selectedItem of the combo, so inside the value object I have something like this

[Bindable]
public function set style(value:String):void
{
_style = value;
trace(value);
}

my problem is that each time I change the combobox selection which in fact change the style property of the value object it does it 3 times, if I trace the value of the setter it actually do the trace 3 times, why?? how can I avoid this? I'm doing something wrong? or there is a better way to do it, please help, thanks for any help

+1  A: 

It's common for data binding expressions to fire many times more than one would expect. I don't know the exact reason. If this causes issue for your app, then don't bind the source directly to the target, instead use invalidation. Bind the source to set a flag, stylesSelectedItemChanged and call invalidateProperties(). Then override commitProperties() and inside your commitProperties(), check if stylesSelectedItemChanged is true, and if so, propagate the new value forward to the destination and reset the flag to false. Be sure to also call super.commitProperties() or else many things would break.

Invalidation is extremely common in the Flex framework, every component uses it internally, and it helps a lot with these kinds of issues.

Sam
well I found the answer of my problem, however you approach is very interesting and for sure I can use it in other situation, you answer indirectly answer an other question I had, thanks a lot :)
goseta
+1  A: 

wow!!, some times writing a question let you think about it twice and let you find the answer by yourself, so I find my own solution, in the documentation said I can make all the properties of an object bindables if I put [Bindable] in the class declaration, so I did it like this

[Bindable]
[RemoteClass(alias='Uniform')]
public class Uniform extends Object implements IEventDispatcher

however when I was trying to dispatch an event in the setters I found in the docs that I must add the event name like this

[Bindable("styleChanged")]
public function get style():String
{
   return _style;
}

public function set style(value:String):void
{
 _style = value;
 dispatchEvent(new Event("styleChanged"));
}

now I found that doing this, mark the property with a double bind and that was making me set the property many times, hugg!, but now I know I can avoid using the second [Bindable] and still the event get dispatch, so now I wonder why I need to use [Bindable("styleChanged")] in the first place if I still can dispacth the event with only [Bindable] and the dispatch method?, weird

hope this help to someone

goseta
This is a second question in an answer to your own question?!?[Bindable] without a name will cause the compiler to automatically wrap the setter in another method that dispatches a "propertyChanged" event and the event object has info on which property changed. [Bindable("somethingChanged")] doesn't change your code at all and indicates that you will dispatch this event yourself. The second form is preferred 'cause the event is unique to the property. I could explain more if this was a real question.. but question in an answer.. comments are limited..
Sam
yeah sorry about that, however is true what you said and works great for me thanks!!!
goseta