Why your Javascript apps need more structure

There are several aspects to building javascript UIs, and you need to do a bit
of planning beforehand if you want them to be successful. 2010 is set to be
the year of Javascript’s ascendancy, and you can’t ignore it. You also need to
start using it properly (if you aren’t already). We have evolved beyond the
level of chucking event handlers inline in views and it is not possible to just
hope for the best as things get more complicated.

I have divided this up into a set of best practices which I try to follow:

Adopt a structure early (MVC)

Think about models properly

Control flow in a declarative way (use Sammy)

Use views to encapsulate the logic for different parts of your application

Communicate between ‘layers’ via custom events

Another thing before diving into this. Think carefully about the target users.
The use-cases I am exploring generally refer to apps rather than
websites. Does your app need SEO? Do visually impaired people need to use
it? Are people with “not-so-smart” phones going to be a concern? If any of these
are important, make sure you don’t build an entirely JS UI, and instead
build HTML which can degrade gracefully using normal http requests.

I have recently been making applications with Canvas and Sockets, and can’t
necessarily rely on the server to generate html for me. Some of the following is
based on these assumptions, and I don’t believe that everything you build should
have this much structure.

I will however attempt to lay out what I see as a new structure for JS
applications. If you’re keen to know what this can look like, see this code
sample from the demo app.

It is also worth noting that I am not trying to provoke a flame war here, but
rather relaying recent experience. People may disagree, and I’m keen to hear
other opinions.

You can usually get away with slowly increasing the complexity of your JS
application until you need to refactor, but it is usually best to start off with
a basic structure first.

I am going to suggest adopting the MVC pattern which has been made famous by
Ruby on Rails in webby circles (though has existed elsewhere for years). It is
a good pattern, and the ideas which make it good for servers can also be applied
to GUI programming.

Several JS frameworks have attempted to give JS apps structure, but I have never
really been taken by them. I have the following constraints when choosing one:

it has to be solid, yet not overly complex

the code needs to feel like Javascript, not some port of a Java beast

the parts need to be understandable, and ideally interchangeable

using existing code beats writing everything from scratch

Sproutcore and Capuccino stop the code feeling like Javascript anymore, and GWT
is too linked to Java backends.

There are also some more lightweight frameworks such as Javascript-mvc, which
wasn’t quite right for me. The Kiwi framework came the closest to what I
wanted, and served as a bit of an inspiration for me. In my case, it still
wasn’t quite right though, hence taking a more polyglot approach.

The primary things to plan are the following:

Models define the domain objects in your application and can be synced
with the server via Ajax or other methods. They often map to database tables,
but you shouldn’t be constrained by this. If you are using REST, hooking them
up with your app should be a doddle.

Views represent parts of your GUI
which you can interact with. They are fed by data, and need to respond to
changes in the data.

Controllers are the intermediaries between model data and the GUI elements
which control them. In a JS app, your controllers manage the changing state
of the views as a whole.

I tend to create directories for these such as /lib/views and lib/models.
Controllers are different and (as I will explain below) sit in a routes.js file
which holds all my Sammy routes.

Since a UI maintains state - unlike most web applications - you can then use
events to communicate between the layers.

You need to think about the Models in your app both on the level of the
individual instances, and as collections of instances. The reason these
collection objects are needed as well as model objects is because these act as
factories. Usually (e.g. in Ruby) this would be taken care of by the class,
which itself is an object, but javascript doesn’t really have classes as such,
so you need a collection object to take its place.

These data sources are used by Views to, for example, populate a list of
people in your account. Additionally these individual instances will have come
from rows in your database, and will therefore need to be created and updated.

Our very own Mr Pickles has recently been working on a library to deal with
this, which he promises to blog about shortly. I won’t therefore go into
much detail on it, and will be using more basic examples in my examples.

There is no definitive way to represent views in a JS app, but I tend to make a
class for them, and pass in a DOM element which exists on the page. I might
therefore have objects similar to the following:

These views are initialised on page load, passing in the data which they might
need to render, eg:

varproject_picker=newProjectPicker($('#project_picker'),projects);

If the collection of ‘projects’ in your app changes, a ‘redraw’ method can be
created which uses the project list for input. There are many advantages to
using a system like this, as View objects can handle the manipulation of their
particular bit of the DOM in response to changes in your datasets. More about
this below in the Events section.

While I have simply injected HTML into the page as a string, there are several
better techniques for doing this. Many templating languages have been created,
such as the one included with Sammy. Personally, I like to replicate html which
exists in the HTML, and let the server do it in one place. What is really bad is
when you emulate html created by the server in your JS, and introduce the
possibility of inconsistencies.

I am also not really fond of servers sending little bits of HTML to update the
page (as is sometimes popular with RJS and the like), and believe that a JS app
be feed data which it manipulates itself.

First off, use Sammy. It is really awesome, and allows you to reach new
heights of declarative page state changes.

If you want to show a form to create a new project, make a link to
#/projects/new which tells your “new project” View to show itself. In this
example I am just manipulating the DOM directly, but you could go via your views, or trigger events:

These are really the heart of building great extensible UIs. This means
utilising the Observer pattern in your objects. I also like to think of it in
pubsub terms: a custom event has 2 parts, the trigger (publisher), and the
events which are bound to it (subscribers).

Create a convention for events which you are going to stick to. I like to link
them to my model names. Hence:

You often need to cascade events, so that the listener for 1 event makes a
change and then publishes a new event. It is cool.

When you use or create a decent library for syncing your Models via Ajax,
you can add callbacks based on your conventions so that a
successful/unsuccessful request to your server triggers the following:

I have made a little demo app, to show how these principles can be used. It
doesn’t use Ajax, but shows you the points where it could be added. This app is
far from perfect, and I don’t want to suggest that the way I chose is the only
one. But I think the code shows what I’m trying to get at.