views:

256

answers:

2

Data binding in ActionScript is really cool. But what if I want to refactor a big switch or if statement inside the curly braces into a function, for example:

{person.gender == 'male' ? 'Mr.' : 'Ms.'}

into:

{salutation(person)}

The compiler doesn't let me do that. I know about properties and I could write getters and setters on the person object. But since I am using inlined JSON objects now that's not convenient(I think). What are other good ways to refactor this code?

To answer Matt's comment. The data type of person is just plain Object. It was decoded from JSON format coming from a service call.

+3  A: 

You'll need to make the Person class (assuming you have one) bindable in order for this to work.

However, since you are saying you're using JSON objects, I'm assuming you just have anonymous objects that were parsed from a JSON string. In that case, I'm pretty sure that won't work. You'll need to create a strongly typed object that has bindable properties.

Just FYI: to avoid having to write custom JSON parsers for every object you want to create, you can create strong typed objects from vanilla objects using a bytearray trick:

public static function toInstance( object:Object, clazz:Class ):* {
  var bytes:ByteArray = new ByteArray();
  bytes.objectEncoding = ObjectEncoding.AMF0;

  // Find the objects and byetArray.writeObject them, adding in the
  // class configuration variable name -- essentially, we're constructing
  // and AMF packet here that contains the class information so that
  // we can simplly byteArray.readObject the sucker for the translation

  // Write out the bytes of the original object
  var objBytes:ByteArray = new ByteArray();
  objBytes.objectEncoding = ObjectEncoding.AMF0;
  objBytes.writeObject( object );

  // Register all of the classes so they can be decoded via AMF
  var typeInfo:XML = describeType( clazz );
  var fullyQualifiedName:String = [email protected]().replace( /::/, "." );
  registerClassAlias( fullyQualifiedName, clazz );

  // Write the new object information starting with the class information
  var len:int = fullyQualifiedName.length;
  bytes.writeByte( 0x10 );  // 0x10 is AMF0 for "typed object (class instance)"
  bytes.writeUTF( fullyQualifiedName );
  // After the class name is set up, write the rest of the object
  bytes.writeBytes( objBytes, 1 );

  // Read in the object with the class property added and return that
  bytes.position = 0;

  // This generates some ReferenceErrors of the object being passed in
  // has properties that aren't in the class instance, and generates TypeErrors
  // when property values cannot be converted to correct values (such as false
  // being the value, when it needs to be a Date instead).  However, these
  // errors are not thrown at runtime (and only appear in trace ouput when
  // debugging), so a try/catch block isn't necessary.  I'm not sure if this
  // classifies as a bug or not... but I wanted to explain why if you debug
  // you might seem some TypeError or ReferenceError items appear.
  var result:* = bytes.readObject();
  return result;
}
Christophe Herreman
Wow! I have not seen this sort of nasty hacking since my Delphi RTTI days. Cool...
Richard Haven
Sick, sick, hack Christophe! I like it. I just might use it.
toby
A: 

fan-flipping-tastic !!

guleesh