API Development

Getting To Know Alloy (Part Two)

This blog post refers to a previous version of Alloy. For updated Alloy reference see the Official Alloy Guides.


The following is the second in a series of in-depth posts introducing developers to Alloy, the new MVC framework for Titanium.
Last time, we discussed some of the architectural concepts around Alloy, and walked through the creation and structure of a new project. In the posts to follow, I would like to focus on the model, view, and controller tiers of Alloy as we build out a simple TODO list application.

Creating Alloy “Views”

In the simple Titanium project we generated last time, a fresh Alloy project was generated in the “app” folder in our Titanium project root:

The “app” directory contains all of our application code and other resources (except internationalization files, which still reside in the [project root]/i18n directory). When we ran the project last time, Alloy’s compiler generated the contents of our [project root]/Resources directory, including modifying Resources/app.js with logic that will initialize and display our application.

Alloy View XML and the Root Component

An Alloy application is composed of numerous self-contained components, but we need one top level component to render the rest of the application. The first component Alloy will display is represented in app/views/index.xml. Initially, this file should contain something similar to the following:

    
        
    

Inside the top-level Alloy tag, there are child tags which should be familiar to Titanium developers as UI controls in the Ti.UI namespace in the standard Titanium API. Alloy has created a declarative markup for the same type of view hierarchy you would manually construct in JavaScript.
The above could also be expressed (in app.js in a standard Titanium app) with something akin to the following (minus any event handling):

var container = Ti.UI.createWindow(),
    label = Ti.UI.createLabel({
        text:'Hello, World'
    });
container.add(label);

Titanium Style Sheets

The Alloy view XML (usually) only represents the hierarchical structure (and content) of the view. The styling and object properties are declared in Titanium Style Sheets (TSS), which are a derivative of JSON. TSS gives us three very powerful features to style the components in our view, which are very similar to the equivalent functionality in CSS:

Style by ID

Using a hash to identify a specific control, we can specify properties we want to assign to a single control within our view hierarchy:

"#aSpecificView": {
    backgroundColor:"white"
}

Style by Class

Using a leading dot to identify a “class” of controls, we can specify properties we want to assign to multiple controls within our view hierarchy:

".someSharedProperties": {
    width:Ti.UI.SIZE
}

Style by Control Type

Using the name of a Ti.UI control, as either a quoted or non-quoted string, we can apply a set of properties to all UI controls of a certain type that are created:

Label: {
    textAlign:'center'
}

In the default application, app/styles/index.tss contains the following style declarations:

".container": {
    backgroundColor:"white"
},
"Label": {
    width: Ti.UI.SIZE,
    height: Ti.UI.SIZE,
    color: "#000"
}

If we add these styles to our Titanium JavaScript example from before, it would look something like:

var container = Ti.UI.createWindow({
        backgroundColor:'white'
    }),
    label = Ti.UI.createLabel({
        text:'Hello, World',
        width: Ti.UI.SIZE,
        height: Ti.UI.SIZE,
        color: "#000"
    });
container.add(label);

Building a simple TODO UI

To illustrate how the view tier of an Alloy application works, I’ve begun implementing a TODO list sample application, based on Addy Osmani’s useful Todo MVC project, which compares client side MVC frameworks in the browser. Since Titanium is built primarily for native apps on touch devices (which will probably have at least some platform-specific UI), this won’t be a 1:1 port. But hopefully, it will give you an idea of how to approach this common sample application using Alloy.
Check out the code for the app below on GitHub.

I won’t go through the code line-by-line, but I would like to call out a few of the highlights. The first thing you’ll notice from the screen capture above is the differences in UI. On iOS, we make use of a standard Cocoa Touch toolbar component. On Android, those same options are exposed when the “menu” button is pressed.
In a standard Titanium application, you would include boolean logic in JavaScript to create one set of UI components per platform. Also, you would write code to add an event listener to the activity object of a Titanium window, and programmatically build out the Android menu. Alloy has provided an easier API to accomplish both of these tasks. Let’s first take a look at index.xml, which defines the overall UI structure for the application:

 

The first thing you’re likely to notice in this example is the platform property. In every UI tag provided by Alloy, you can specify a platform property on an XML node, which can be “ios”, “android”, or “mobileweb” currently. When the Alloy compiler is run, the code generator will skip those portions of the view XML altogether, resulting in no Android code shipping on iOS, and vice versa. It also provides a nice, declarative way to specify how the app will be structured differently on one platform versus another.
The second thing you’re likely to notice is the new “Menu” and “MenuItem” tags. This is a special Alloy-specific feature which abstracts away the details of the Titanium API for Android menu creation (Android activities and lifecycle events, etc). Using this syntax, you can create the menu UI and specify event handlers just like you would any other Alloy components.
The other item I will point out in this example is the use of the Require tag. To break up your application into smaller components, you can generate new view/controller/style triads from the command line using alloy generate controller [name of component]. This will create a new view XML, TSS, and controller file which you can use to implement a new subsection of your application. To insert on of these components into the application, you can use the Require tag as in the example above, passing in the controller name as the src property.
You can programmatically create view/controllers as well using something like var myController = Alloy.createController('someController') in JavaScript, which will return an instance of a controller object. To get the Titanium view proxy object which represents the root of the view hierarchy in the view/controller, you will use myController.getView()
One other thing to point out in this first version of the TODO list application is the use of a shared TSS file for the entire application. [project root]/app/styles/app.tss contains shared style classes and Component-level style declarations you’d like to use across the entire app:

Window: {
    backgroundColor:'#fefefe',
    exitOnClose:true,
    navBarHidden:true
},
Label: {
    color:'#000'
},
'.dottedLine': {
    backgroundImage:'/dots.png',
    backgroundRepeat:true,
    height:'1dp',
    bottom:0,
    opacity:0.3
}

One other thing that may be slightly confusing is the opening/closing of windows. Alloy creates a view hierarchy for you, but does not automatically “open” Titanium windows. In index.js, you’ll notice the only line in that controller file (for now) is a call to open the root window of the application. You must still (for now) handle this in JavaScript while using Alloy.
Clone this TODO sample application and step through the code, beginning with index.xml, index.js, and index.tss. From there, start drilling down into the required components to see how the UI for this application is structured. In the next post in this series, we will dive deeper into the model and controller tiers of the application to see how we approach event handling and data access, to get a full view of what Alloy brings to the table.