Reusable Components

There was a lot of grumbling when Titanium 1.8 came out, and CommonJS was introduced. People had built apps using the best practices of 1.7, but suddenly there were a whole new set of best practices. It took me a bit to get used to the syntax, but once I got over that hurdle, the lightbulb turned on. Coming from a Flex background, it dawned on me that I could finally make my Titanium apps more object-oriented.

I keep seeing code in the Q&A that frankly makes me cringe. The strict-typing in actionscript forced me to use some great best practices, and CommonJS lets us move closer to that style of coding.

I figured that the most common UI element that gets reused in any app is the humble TableViewRow. So, let’s look at my BeerRow module:

The first thing you’ll notice is the retina variable I set once in the module. Like the comment implies, most Ti.Platform calls are expensive, so you should do your best to minimize those calls.

Next, there’s the BeerRow method, which takes a beer object as a constructor parameter, and returns a TableViewRow. The code inside is pretty standard, creating a row, adding a picture and a title. This row is overloaded though, where I add the getter and setter methods pushBeer and pullBeer, respectively. Since the actual ImageView and Label objects won’t be accessible to the outside world, the pushBeer method has to update those for us. Note that the slightly unconventional names are because you can’t add methods that start with “get” or “set” to Titanium proxy objects.

Last, we assign our BeerRow method to module.exports, because, well, that’s how CommonJS modules work. I really like the coding conventions of actionscript, where object classes are UpperCamelCase, and variables are lowerCamelCase, so you’ll notice that my filename and constructor methods are both BeerRow.

So, we have this wonderful row, how do we use it? It’s actually very easy to do:

First, we use require() to include our module. Again, I give my variable the UpperCamelCase so I know it’s the object itself, and not an instance of the object.

Next, I’m looping over my beers array and creating a row for each one. We create an instance of our BeerRow using new BeerRow(beers[i]).

Just after that, I add a click event listener. Inside that event listener, you can see I call my custom getter method, pullBeer, to display the name. Typically, you would probably take that beer object and use it in the constructor of a new window.

I add the row to my array of rows, and then set the TableView’s data to that array. Now you’re playing with code-reuse!

You can find the full source-code for this sample application in my blog-samples project on GitHub.

Comments