membersound
membersound

Reputation: 86885

Bidirectional binding for flex ComboBox?

I have a collection that I want to bind as data input for a ComboBox:

private static var LOGOS:ArrayCollection = new ArrayCollection([
 {index:0, label=logo1}, 
 {index:1, label=logo2}
]);

<s:ComboBox selectedItem="@{model.labelIndex}" labelField="@label" dataProvider="{LOGOS}" />

Now, when selecting an item, the binding should send the associated index property of the objext to the model and update labelIndex. Of course it does not work as above, because labelIndex is of different datatype than the ArrayCollection.

[Bindable]
private var model:MyModel;

[Bindable]
class MyModel {
   public var:Number labelIndex;
}

Question: how can I map the array element to the model and vice versa?

Upvotes: 1

Views: 173

Answers (1)

f.poller
f.poller

Reputation: 198

What you are looking for will require some scripting, binding isn't smart enough to figure out how to handle this on its own.

You can use the BindingUtils class to define the bindings, and use the chain argument of the bindProperty method to modify how values are being looked up.

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html

For the combo.selectedItem to model.labelIndex binding, you can specify the chain as an array, where the elements define the path where to look for the value:

BindingUtils.bindProperty(model, 'labelIndex', combo, ['selectedItem', 'index']);

This will bind to the selectedItem property, and pass the value of the items index property.

The other way around is a little more tricky and will require using a getter function which grabs the object from the datasource, based on the labelIndex value:

BindingUtils.bindProperty(combo, 'selectedItem', model, {
    name: 'labelIndex',
    getter: function(host:MyModel):Object
    {
        return LOGOS.source.filter(function(item:Object, index:int, array:Array):Boolean
        {
            return item.index === host.labelIndex;
        })[0];
    }
});

This will bind to the labelIndex property, and the getter function will be invoked when the property changes. The function will filter the datasource based on the models changed labelIndex property value, and return the source object with the matching index property value, which will finally be set for the combobox selectedItem property.

Your combobox definition will of course need an id in order to be targetable via script

<s:ComboBox id="combo" dataProvider="{LOGOS}" />

Note that there's no need forthe the @ in the labelField property, this is only used with XML datasources where you need to target an attribute. However, actually you don't need to specify this at all, since label is the default value of the labelField property.

Upvotes: 2

Related Questions