Wednesday, January 16, 2013

Two-way data-binding with Laces.js Tie

This post will sidetrack a bit from the conventional PlainText blog, to cover a JavaScript library I wrote to assist with the map editor. If you have no interest at all in JavaScript, feel free to skip this post :)

The PlainText map editor is an HTML5 application that has to maintain a complete model of the game world on the client. On startup, it fetches all Areas, Rooms and Portals from the server, and keeps them in its own model, feeding changes back to the server.

Apart from feeding back changes, there are various views that all need to properly reflect the model. There's the main canvas view showing a graphical layout. There's the sidebar showing information of the selected Room. There's an Areas menu and an Areas editor. There's a Portal editor. Keeping all these views in sync meant that I needed to have a proper model, with proper data bindings so that various modules could be notified of changes. For this purpose I created my own model micro-framework: Laces.js.

Laces.js by itself provided just the model that I needed, but why stop there? With Laces.js any module could bind to the model, so that they could update their view. But why not create a direct binding between the model and the view, so that no (or at least less) manual updating is necessary? And what if changes to the view could directly be fed back to the model? This is called two-way data-binding, and it's traditional territory to MVC frameworks. But I didn't want a full-fledged MVC framework*, yet I did want two-way data-binding.

Meet the Laces.js Tie add-on.

Let's say we have a model variable that has a selectedRoom property. selectedRoom can by null, but it may also be a Room object, with properties such as id, name, description, etc.. This model itself could be created like this (we'll ignore any other useful things the model might have for now):


Now let's say we will want to show the name and description of the currently selected room. We can do this using a Laces.js Tie:


The above code will literally tie the HTML fragment to the Laces.js model, making sure the HTML stays up-to-date when the selectedRoom property or its subproperties change. But we can take it further by allowing inline editing of the properties:


Now when someone double-clicks one of the properties, it will turn into an input field, and when they make changes, those will be automatically saved to the model. Of course you can customize what event you prefer to use for editing. So if you want to enable editing through single click:


Besides plain HTML strings, you can also tie your model to a multitude of template engines. Laces.js Tie has already been confirmed to work in tandem with Handlebars.js, Hogan.js and Underscore.js' built-in template engine.

If you want to know more about Laces.js or the Laces.js Tie add-on, just check the project page.

*) Check the Rationale on the Laces.js project page for why I didn't want this.