Enhancing Titanium: Using staballoy to enable simple data-binding

Rene Pot
All Titanium
Published in
4 min readSep 5, 2018

Data-binding in Alloy is pretty straightforward when you’re using models and collections to store your data. However, with things that are just singular, like a profile picture, a username or just certain colors/properties, you don’t really need models. And then there is no option to do data-binding really.

Of course, you can do it manually with global events or something similar, but that really is complicated and hard to forget it is there.

I wanted to make something that could do this for me, triggered when I was working on an app that had a profile picture and username in many places throughout the app. Creating a “user” model just for that was a bit too much effort for something so simple, and I was sure I could reuse this technology for many other purposes.

So what is staballoy

So staballoy was the solution I came up with. It is a small library on top of Alloy, overriding the Alloy.createController functionality. When creating any controller this method is called, so staballoy overrides the method to allow data-binding to work. Internally it functions the same so staballoy is backwards-compatible with any Alloy project out there.

What it does though, it parses every element in your controller and looks for any properties that want to subscribe to certain data.

Are you using any other library that overrides Alloy.createController? In that case staballoy won’t be compatible with it, keep that in mind. Luckily there are only a very few libraries out there doing it.

How do you include staballoy?

Simple! Just include it in alloy.js:

var staballoy = require('staballoy);

Because we’re defining a variable in alloy.js, keep in mind this is also a global. Which in this case is a good situation, as you want access to staballoy everywhere. So now in every lib/controller you can reach it right away.

But before doing that, you of course need to include the library in your application. You can find it on npm!

From now on, any UI element in your entire app will be parsed by staballoy. But keep in mind, only UI elements created using Alloy are included.Any manually created UI elements using Ti.UI.create will not be parsed and won’t work out of the box with staballoy. See this as a good reason to start making your apps fully in xml instead of mixing.

Populating variables

Now the reason why you want staballoy in your app. You can subscribe to variables defined inside staballoy. But of course these variables need to be populated first. Keep in mind these variables aren’t permanently stored, but are session based. So, a good practice is to populate the variables as soon as you can get access to the data. For a lot of cases this means you can populate it inside alloy.js right below the staballoy inclusion.

staballoy.setVar('user', {"name": "Foo Bar", "picture": "/images/image.png", "xp": 431});

If you need to populate a variable inside a controller, staballoy has injected the methods inside it through arguments.

$.args.staballoy.setVar();

Subscribing to variables

Now of course comes the real reason you want to use staballoy. Subscribing to variables. Every time the variable is updated through the setVar method, no matter where in the app, everything bound to it will update automatically. The easiest way to subscribe is straight through tss. We’re going to bind the text of a label to the username property we defined earlier.

So imagine we have this label:

<Label id="username" />

We can bind that to the variable defined earlier using this in tss:

'#username': {
staballoy: {
subscriptions: {
"user_name": "text"
}
}
}

As you can see we’re using user_name for the binding. This is the user variable, with the name property inside. Instead of using user.name we’re having to resort to using _ due to limitations in Alloy. Read more about deep setting/getting in the staballoy readme.

So now, with just the tss adjustment, the label will always be up-to-date. Even if the controller is in the background, not created yet, or in another tab. You’ll never have to worry about it having the right value. Even if the variable is set after you’ve bound to it, it will still work.

Transforming data

One extra step we can do is transforming data before applying it to the UI. This is great for things that aren’t properly reflected 1-on-1 from data to visualization. Take XP for example, that doesn’t usually reflect the percentage of progress automatically.

<Label id="xpProgress" />

We’re, again, going to use the user object stored earlier, but this time we’re adding the logicFunction

'#username': {
staballoy: {
subscriptions: {
"user_xp": "text"
},
logicFunction: "parseUserXP"
}
}

Then we’re going to create the function it references on the $ namespace.

$.parseUserXP = function(value){
var progress = value * 0.2; // calculating % based on 500
return progress + '%';
}

This method will calculate a percentage, assuming the 100% value is 500. Of course in real life calculating progress based on XP usually depends on levels, but for sake of example we’re keeping it simple. It then returns the percentage with a % added to it. The return value in turn is then put on the text property of the label as displayed in the subscriptions part.

Two-way data-binding

The feature I love the most is the most recent add-on, two-way data-binding. This works out-of-the box if you bind with the value property of any element that supports it.

Conclusion

Staballoy brings data-binding to the next level. It allows you to bind simple data to certain elements without the need of models. In theory it can replace models as well, but I’d recommend against that.

I am very curious if you’ve implemented staballoy in your apps! Where you use it for and if they’re in production.

You can read all the docs of staballoy on npm or of course the relevant GitHub repository.

--

--