Monday, May 9, 2011

DataItem: Bindable Objects for DataGrid Examples

Many Flex SDK examples include  untyped sample data defined with fx:Object like this:

  <fx:Object index:123 text:"Hello World"/>

The fx:Object MXML tag is similar to using ActionScript's Object literal syntax:

  {index:123, text:"Hello World"}

In both cases the result is a dynamic untyped object instance with three properties.  If you use objects defined this way as List or DataGrid dataProvider items and your item renderers bind to the dataProvider properties then the SDK runtime issues warnings like this:

    warning: unable to bind to property 'index' on class 'Object' (class is not an IEventDispatcher)

A warning of this kind will be issued for each object and each property your renderer attempts to bind to.  What the warning is trying to tell you is that it has used the binding to get the initial value of the 'index' property but it will not detect subsequent changes to the property.  In other words it's not functioning as a "binding so much as an initialization.

To make a property bindable you need to include a [Bindable] metadata statement in the property's definition, and to do that you'd need to define a new concrete ActionScript class like:

  public class MyDataItem
  {
      [Bindable] public var index:int;
      [Bindable] public var text:String;
  }                              

Given that, you could define instances of MyDataItem in your MXML application and safely bind to them Here's a demo and the source code.
MyDataItem: Concrete class with [Bindable] properties

Defining a concrete class with bindable properties is most efficient and flexible way to define application data.  However in small examples or prototype applications we often prefer to use fx:Object because it's a little simpler and eliminates the need for a separate class definition.  The Spark DataItem class is a replacement for fx:Object that defines bindable properties.  It's called DataItem because it's typically used to create data provider items for Lists or DataGrids.

In the following Spark List example DataItem is used to define the list's dataProvider items and typicalItem.   The application includes a slider with id="slider" and the list's dataProvider, is defined like this:

  <s:dataProvider>
      <s:ArrayCollection>
          <s:DataItem
              min="{slider.value - 25}"
              max="{slider.value + 25}"
              value="{slider.value}"/>
          ...
      </s:ArrayCollection>
  </s:dataProvider>

So each DataItem has bindable properties named min, max, value, and those properties are bound to the slider's value.  The item renderer is defined like this:

  <s:ItemRenderer fontSize="24">
      <s:Label text="{data.min} {data.value} {data.max}"/>
  </s:ItemRenderer>

Remember that an item renderer's data property is alway set to the dataProvider item the renderer is to display, so expressions like "{data.min}" are bindings to a DataItem property.

Here's the application itself, and the source code.

No comments:

Post a Comment