Don't like this style? Click here to change it! blue.css

Class 17: Templating and Data-Binding

I'm in the mood to look at javascript trends, not by the libraries that promote them, but by the problems that need solving. In this way we can see the modern trends as their modern design patterns. In this case I want to look at some evolving trends which make interactive development much nicer (and pave the way for web components): templating engines and data-binding.

Popular Templating Libraries

Rather than start with the vanilla version I'm going to have you make a working example using a popular library. Then we'll look at what we can do on our own.

Underscore Templating

Here is a simple underscore template example:

JS Bin on

Underscore templating is powerful in that it either reads a value using <%= key %> or raw javascript using <% code here %>. Here is an alternate template for the same "page":

JS Bin on

Congressional Dating Site: Use to get JSON data on all of the current members of congress. Use underscore templating to make a site with congress members and their Twitter handles.

Moustache Templating

Another popular templating format is moustache style, also called handlebars, and other facial hair references. They are names this way because the :-{( braces can be seen as soup strainers.

See the Pen eJjVKK by Andy Novocin (@AndyNovo) on CodePen.

This example is using handlebars.js which has {{keyname}} as a way to replace the appropriate value. For loops they have two methods either a {{#keyname}} and {{/keyname}} or the keyword {{#each keyname}} and {{/each}}. Likewise {{#if propname}} works too.

Political Watchdog Site: Use the current list of resolutions and bills in congress at (114th congress will be dated at some point so update to your congress number) to make a site which lets users view the titles and click through to get more data. (Using handlebars.js as your template engine.)

DIY templating

So I'll go through how you might build your own simple templates in some progressive steps:

JS Bin on

This snippet shows how to create a simple "Regular Expression" in Javascript and inject it into a replace function. If you haven't played with regular expressions before, take a day (maybe on Saturday) and learn them. It is AWESOME and it makes you feel like this:

Be a super-hero

So that snippet looked for something which matches {{name}} and replaced it with the actual name value from context. Now let's have that work for all of the attributes in context instead of something specific:

JS Bin on

Array Parsing? If you're feeling up to it, update your DIY template to allow {{#keyName}} to repeat the parts from there to {{/keyName}} for each element in the array stored there {keyName: [obj1, obj2, …]}. (Just like the handlebars example.)

DIY templating is great if you have a very simple task and don't want to pull in a huge library. It loses out on some features and you don't get the benefits of expert worship, but I say you become the expert that others trust instead.


So now that we've got some nice templating solutions I want to look at another concept which ripples through javascript frameworks and applications: data-binding.

The following snippet is why Angular became popular (IMHO):

See the Pen adjYyb by Andy Novocin (@AndyNovo) on CodePen.

The idea is simple enough, when the state of an object changes we should be able to map that state to an HTML element as simply as possible. The other direction is when an HTML input has a value update a specific attribute of a given model should automatically change.

So what sort of vanilla DIY data-binding can we do? By using getters and setters we can emit events whenever a model changes. By using a 'render' function we could redisplay the model's state. Using 'change' listeners we can update models. Perhaps a vanilla ideal I might strive for is:

      model.inputs = {
      '#thisInput': 'thisModelKey',
      '#otherInput': 'thatModelKey'};
      model.listenTo('change', model.render, model);
      //line stolen from yesterday

DIY binding: create a person instance with first Name and last Name. Make an output with their full name and two inputs one for first name and one for last name. Have the screen update as you change either name.