Data Binding with Objects

Recently I started to see more and more cases when people have to abandon strongly typed classes but want to keep an ability to keep binding working. Here is a brief recap of typical problem/solution.

Flex Framework usage of binding is one of the most important productivity features. Ability to declaratively define reaction to the changes in the data or components state greatly simplifies programming and reduces errors related to low-level coding.

In order for binding to work you need to make sure changes to the data are known to the framework. Unlike most of dynamic languages implementations, ActionScript 3 is built for speed and heavily utilizes direct access to the properties and methods. In this situation the only way for data to notify the world about the changes is to embed the code to fire chamge events.

Flex compiler helps in a big way by introducing [Bindable] and [Managed] tags. If you prefix your variable with [Bindable] tag, compiler does the following:
1. Inspects every public property and setter of you variables class and generates wrapper getters/setters that adds event notification.
2. Every time “bindable” property is being used, compiler references these getters/setters instead of original properties

Obviously it does not work too well with dynamic data of type “Object” coming from server. The problem is alleviated a bit by the fact that Flex would automatically wrap the Object in the ObjectProxy if default value of “makeObjectBindable=true” of the service is not modified. However, it will wrap only the top level and not the individual array members making changes to those undetectable. For example, if you are passing set of the objects from assembler, and the members can have arrays, the changes to the rows are not going to fire change events unless you explicitly wrap every array element in the object proxy.

Here is an example:
private function onResult(r:ResultEvent) : void {
var quotes:ArrayCollection = r.result.quotes;
var wrappedQuotes = new ArrayCollection();
for each (var quote in quotes)
wrappedQuotes.addItem(new ObjectProxy(quote))
view.dataProvider = wrappedQuotes;
}

ObjectProxy is very expensive and should not be used with large amount of data. For large datasets please consider strongly typed classes that will support [Bindable] on members level.