AngularJS: About Those Custom Attributes...

2012-09-06 00:00:00 +0100 by Alex R. Young

The first thing I noticed on the AngularJS homepage was the use of a non-standard attribute, ng-app:

<div ng-app>
    <input type="text" ng-model="yourName" placeholder="Enter a name here">
    <h1>Hello {{yourName}}!</h1>

Suspicious as I am, I wanted to look into this further. Running a more complete HTML5 example through the w3.org validator shows errors for each ng- attribute:

Earlier HTML specifications state that unrecognised attributes should be ignored, so this should be safe enough -- clients will generally ignore the unrecognised attribute and JavaScript can handle it as required by AngularJS.

The AngularJS developers have gone a step further to quell fears of rogue attributes causing unexpected issues: it now transparently supports data- prefixed attributes. That means the previous example could be written with data-ng-app and it would still work. I tried it out and found that it even copes with mixed attribute styles.


Unlike AngularJS, Knockout embraced data- attributes from the beginning. The documentation even clarifies the use of data attributes:

The data-bind attribute isn't native to HTML, though it is perfectly OK (it's strictly compliant in HTML 5, and causes no problems with HTML 4 even though a validator will point out that it's an unrecognized attribute). But since the browser doesn't know what it means, you need to activate Knockout to make it take effect.

Although AngularJS now fully supports this approach, using custom attributes may have hurt early adoption.


The underlying mechanism that AngularJS uses to support multiple attribute prefixes is Directives, which according to the documentation turns HTML into a "declarative domain specific language". You may have noticed that AngularJS templates are HTML -- this contrasts with many other frameworks that use a string-based template system. Since templates are HTML, the entire page can be loaded and parsed by the browser. The resulting DOM is traversed by AngularJS's compiler to find directives. The resulting set of directives is associated with DOM elements and prioritised. Each directive has a compile method, which can modify the DOM, and generates a link function.

Links are live bindings, and splitting compilation into stages like this means AngularJS can do a certain amount of work before repeatedly rendering sets of elements. The example in the documentation is rendering lots of list elements:

The result of of the li element compilation is a linking function which contains all of the directives contained in the li element, ready to be attached to a specific clone of the li element.


Although AngularJS may have been treated with some trepidation due to the adoption of non-standard HTML attributes, the authors have identified this and it's possible to write applications that will validate. The "declarative domain specific language" concept is definitely interesting, and the two-stage compilation process has some advantages over other schemes that I've seen.