views:

251

answers:

4

Not an easy question to decipher, so let me boil it down. I'm trying to convert an MXML component to an ActionScript Class. The component consists of a Form with a TextInput, TextArea, and two buttons - Save and Cancel, and a Validator for the TextInput, and other logic to handle events that occur. This component is currently extended by several other components.

Now, in the MXML component binding the TextInput text property to a property in an Object was very easy:

<mx:TextInput text="{_itemToEdit.name}" />

But in ActionScript, I'm creating the TextInput and setting the text property before the Object is set, and the TextInput is not being updated:

public var itemToEdit:Object = {};

private var nameInput:TextInput = new TextInput();

public function MyClass()
{
    nameInput.text = itemToEdit.name;
}

How can I make sure that the TextInput text property is bound to the specified property in the Object?

A: 

Apparently it's slightly more complex than a simple assignment to bind purely in AS, here's a couple tutorial/docs to show you how to pull it off.

http://cookbooks.adobe.com/index.cfm?event=showdetails&amp;postId=6802

http://raghuonflex.wordpress.com/2007/08/30/binding-in-mxml-as/

JStriedl
Still not working for me...I guess I"m doing something wrong somewhere else...Not really sure how I can debug a Binding....
Eric Belair
You must be doing something wrong since BindingUtils is essentially how all of the MXML-based bindings in Flex are implemented in generated ActionScript. Can you post the code you tried to use?
cliff.meyers
Like I said in the other post, MXML binding also sometimes have issues detecting changes to properties of Objects. That could be what's happening here.
Glenn
A: 

Compile your MXML component with the -keep option. Examine the ActionScript code that was generated by mxmlc and do something similar.

You may also do it using the Proxy object - I blogged about it over here: http://flexblog.faratasystems.com/?p=433

Yakov Fain
I tried that, but my base Class is in a Library project, and I can't get the generated ActionScript for the Class.
Eric Belair
You don't need a base class. Create the class in the main proj that has a code snippet from your original post and take a look at the generated code. Besides, the compc compiler accepts -keep too.
Yakov Fain
A: 

If "itemToEdit" is a pure AS3 Object, then the binding probably doesn't work properly anyway. That is, it will work when the object is initially created, but any changes to "name" in the object won't be detected. (I could be wrong...haven't done extensive tests)

Anyway, your problem is easy to solve with getters/setters:

private var _itemToEdit:Object;

public function get itemToEdit():Object { return _itemToEdit; }
public function set itemToEdit(value:Objecy):void {
  _itemToEdit = value;
  nameInput.text = value.name;
}

Binding isn't necessary here.

Glenn
Unfortunately, this won't work in all cases - if I update the property at some other point (which is what I am doing), the setter is not called.
Eric Belair
This is starting to sound like an architecture issue. You can have separate getters/setters for the property itself, setting the value in the Object and in the input. Or you can have a central spot to make changes to the Object's properties and dispatch notifications when that happens. See one of the MVC frameworks for AS3 (PureMVC, Mate,etc..)
Glenn
+1  A: 

Binding is all about firing change events. you'll need to modify your 'itemToEdit' class to be an EventDispatcher for this hack to work. here goes

//item to edit class
private var _name:String;

public function set name(value:String):void
{
    _name = value;
    dispatchEvent(new Event("NAME_CHANGED"));
}


//whatever the binding class is
private var _itemToEdit:ItemToEdit;
private var _textField:TextField;

public function set itemToEdit(value:ItemToEdit):void
{
    if (_itemToEdit) removeEventListeners();
    _itemToEdit = value;
    if (_itemToEdit) addEventListeners();
}


private function addEventListeners():void
{
    _itemToEdit.addEventListener("NAME_CHANGED", itemToEdit_nameChangedHandler);
    itemToEditChangedHandler(null);
}

private function itemToEdit_nameChangedHandler(event:Event):void
{
    _textField.text = _itemToEdit.name;
}

Obviously this was done just for speed, you'll need custom events and some better names etc, but this is the basic jist.