API Development

Data-binding Made Easy with Alloy: Part 2

In the first part of this series, we looked at using the Titanium Alloy MVC framework, with its built-in Backbone.js data-binding, to easily bind data to Views with minimal code.

(This post assumes you’ve followed along with Part 1 which was using a mock library to generate models and collections — things are a little different if you use the “stock” Alloy Model definitions — I’ll cover the benefits and differences of both in Part 3)

That’s great for lists, but what about “detail” views — where you’d like to show a single instance of a model in a view / controller?

Traditionally in Titanium, you might do something like this:

Alloy.createController("detailView", data).getView().open();

where data is either the value or object you want to pass across, then in the detailView controller you might do the following (assuming data contained an object with properties):

$.firstName.value = args.firstName;
$.lastName.value = args.lastName;

This is fine of course, but it requires you to bind the data manually in the controller to every element in the view – and that means writing more JavaScript.

Alloy provides a much simpler way of doing this by passing across a model itself and then binding using the built-in data-binding of Alloy itself, meaning little or no JavaScript is required.

To use this you use a special $model parameter when passing the data to the controller. So, for example, if you’d obtained a model from a TableView with:

function onClick(e) {
Alloy.createController("detailView",{
$model: Alloy.Collections.contacts.at(e.index)
}).getView().open();
}

Depending on how you’ve created your models and controllers (for example if you’ve created them outside of the normal model definitions folder), you may need to do a .transform() on the model before passing it to the controller.

In this case, you would do the following:

function onClick(e) {
var model = Alloy.Collections.contacts.at(e.index);
model.transform();
Alloy.createController("detailView",{
$model: model
}).getView().open();
}

In this example, a transform method is being called against the model — this basically does a toJSON() on the model and exposes the data in the _transform property.

If your models support / have a transform function, that’s all you need to do — if not, you would need to manually add this so that it created the JSON property for you.

With this in place, the detail view itself just has to contain standard XML that maps the model properties to the view:

<Window>
    <View layout="vertical">
        <View>
            <Label class="caption">First Name</Label>
            <TextField value="{firstName}"/>
        </View>
        <View>
            <Label class="caption">Last Name</Label>
            <TextField value="{lastName}"/>
        </View>
    </View>
</Window>

The above example is indicative — some styling has been omitted.

If you do want access to the model itself in the controller code, you can do that by referencing:

var firstName = $model.toJSON().firstName;

Simple as that — data binding in detail views made easy with Alloy.

For more guides check out Alloy Data Binding and the backbone.js documentation, and please leave a comment!