Flex Warning: Unable to bind to property 'foo' on class 'Object' (class is not an IEventDispatcher)

Adam Tuttle picture Adam Tuttle · May 29, 2009 · Viewed 35.2k times · Source

I've got an object that contains a dozen or so fields I want to bind to form elements, so that I can use that object to send the data back to the server to be saved.

Definition of my container object:

private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:Object = emptyLink;

currentLink is assigned at runtime to a specific index from an ArrayCollection, I'm just using the emptyLink object for initialization purposes, mostly.

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
    <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
        <mx:TextInput id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" />
        <mx:TextInput id="trigger2" width="100%" textAlign="left" text="{currentLink.trigger2}" />
        <mx:TextInput id="trigger3" width="100%" textAlign="left" text="{currentLink.trigger3}" />
        <mx:TextInput id="trigger4" width="100%" textAlign="left" text="{currentLink.trigger4}" />
        <mx:TextInput id="trigger5" width="100%" textAlign="left" text="{currentLink.trigger5}" />
    </mx:VBox>
</mx:Panel>

Of course, this compiles and displays just fine, but there are runtime warnings for each instance:

warning: unable to bind to property 'trigger1' on class 'Object' (class is not an IEventDispatcher) warning: unable to bind to property 'trigger2' on class 'Object' (class is not an IEventDispatcher) warning: unable to bind to property 'trigger3' on class 'Object' (class is not an IEventDispatcher) warning: unable to bind to property 'trigger4' on class 'Object' (class is not an IEventDispatcher) warning: unable to bind to property 'trigger5' on class 'Object' (class is not an IEventDispatcher)

And the currentLink object is not updated when the TextInput fields are changed.

The obvious answer is that my object needs to be an instance of a class that implements IEventDispatcher. What that answer doesn't tell me is the particulars of implementing that interface (what's required? what's not?), and if there is a simpler way to do this -- like a built in class that will gladly accept my custom properties and allow for binding, without me having to worry about the particulars of implementing the interface.

Does such a class exist? If not, what's the bare minimum and/or accepted standard for accomplishing this task?

Answer

Gabriel picture Gabriel · May 30, 2009

You need to use ObjectProxy (as Chetan mentions) - but you also need to use valueCommit to get the text you enter in the input BACK into your object:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectProxy;
              private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);


private function handleClick():void
{
    trace(currentLink.trigger1);
}
]]>
</mx:Script>

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
        <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput  id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" valueCommit="{currentLink.trigger1 = trigger1.text;}"/>

                <mx:Button label="Click" click="handleClick()"/>
        </mx:VBox>
</mx:Panel>        

</mx:WindowedApplication>