The Limits of Templating as a Declarative View Solution

I've been playing a little bit lately with AngularJS. Angular is one of a spate of new JavaScript frameworks that provide powerful tools for building interactive web sites and web apps by capitalizing on mature patterns and practices that have served well in the "native client" space. Most of these frameworks provide some sort of separation of concerns between the "view" and the "model".

The "big four" frameworks in this space are AngularJS, KnockoutJS, Backbone.js, and Batman.js. All four of these frameworks are primarily concerned with finding ways to purify and simplify two parts of the architecture of most modern applications: the UI (a.k.a. view, in this case, the HTML), and the model that sources the information in the UI. The primary obstacle in the way of achieving this goal is something called data-binding, which is a terse and useful term for synchronization of the dynamic information displayed in your UI to the state of an object model in your application.

AngularJS goes about this in a strikingly different way from the other three frameworks. The developers of Angular elected to use HTML "templating" as the mechanism of data-binding. Which is to say, you take a "template" of your web page, poke holes in it where you want your dynamic information to go, and then place in those holes small bits of syntax which tell the templating engine how to build the HTML to fill the holes at runtime. Below is a simple example of a template, as it would appear in an application built with AngularJS. If it looks familiar, that's because it's my own modified version of the front page demo from the AngularJS website. Be sure to note the fidelity of the template to the HTML it will produce. It's very clean, and you can see clearly the features of the document in it.

Templating is great for producing a document on demand using data that isn't known until runtime. It's a technique that has been around for quite a while now, and we've mostly figured out some really convenient syntax and conventions for doing it. Heck, ASP.NET MVC is a template-based solution for creating HTML on the fly. It works fantastic. But MVC is not dynamic once that document leaves the server. It builds the HTML once and sends it off to the client, never to revisit it again. The next document it serves up will be a whole new document in response to a whole new request. This is very different from the way Angular uses templating on the client, where the same document may be changed and re-rendered hundreds of times, or more.

Here I feel this solution starts to strain, and this bothers me about Angular as a general solution for web apps. Let me be clear, I think it may be a fantastic way of building static pages, interactive forms with a dash of business logic, or generally anything where there isn't need for complex logic, or generation of large swaths of HTML from nothing. But as pages become more dynamic after the initial rendering, the templates can become bloated and less emblematic of the produced document structure. Today web pages are commonly less about content, layout, and flow, and increasingly about interactivity, dynamism, and tasks. This impacts a templating solution in that expressions expand and dominate, and eventually replace, their HTML content containers. The bulk of logic starts to move further away from the template and deep into javascript and framework internals start to leak out. As an example, see the introduction page on creating your own "custom elements" in AngularJS. We've obviously stepped far away from a "templating" solution here.

For extremely dynamic sites where most of the elements on the page are subject to change in some way or another and very little can be considered "static", I think more conventional solutions are more appropriate. At that point, it becomes appropriate to move logic as much as possible into code, where it can be encapsulated in objects and layers with clear roles and identities. Here it may be prudent to start considering Backbone, Batman, Knockout, or maybe even something else.

For myself, I'd love to see a JavaScript framework that employed MVVM in an unobstrusive way, by treating the HTML document as a passive view which is bound to at run time. I can always drop in Mustache templates for creating HTML in small bits where needed. And "declarative bindings" can just as easily be achieved outside of the HTML, via a nice fluent API. Does anyone know of a framework like that?