The first thing I noticed on the AngularJS homepage was the use of a non-standard attribute,
<div ng-app> <div> <label>Name:</label> <input type="text" ng-model="yourName" placeholder="Enter a name here"> <hr> <h1>Hello !</h1> </div> </div>
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
- Attribute ng-app not allowed on element div at this point.
- Attribute ng-model not allowed on element div at this point.
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.
data-bindattribute 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
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
lielement compilation is a linking function which contains all of the directives contained in the
lielement, ready to be attached to a specific clone of the
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.