Markup in angular is a feature that you can use in templates to transform the content of DOM
elements prior to the compile phase (in which elements are compiled and link functions are
returned. See the compiler docs for details on how the compiler
works.) The ability to make pre-compile changes to DOM elements lets you create shorthand for
widget
and directive
declarations.
Angular provides one built-in markup feature: the double curly-braces used to declare binding points (between the model and view) for angular expressions. You can also create your own custom markup.
{{ }}
)The double curly-brace ({{ }}
) markup translates an enclosed expression into an ng:bind
directive:
{{expression}}
is transformed to:
<span ng:bind="expression"></span>
Markup is useful for the simple reason that {{1+2}}
is easier to write and understand than <span
ng:bind="1+2"></span>
. After markup shorthand is expanded into the DOM elements it represents, the
expanded elements are then compiled normally.
Let's say you want to define markup that transforms ---
into a horizontal rule (<hr/>
):
header --- footer
should translate to:
header <hr/> footer
Here is how you could extend the angular compiler to create the "---" markup:
angular.markup('---', function(text, textNode, parentElement) { var compiler = this; var index = text.indexOf('---'); if (index > -1) { textNode.after(text.substring(index + 3)); textNode.after(angular.element('<hr>')); textNode.after(text.substring(0, index)); textNode.remove(); } });
Unlike the way the compiler processes widgets
and directives
(matching the name of the handler function to a DOM element or
attribute name), the compiler calls every markup handler for every text node, giving the handler a
chance to transform the text. The markup handler needs to find all the matches in the text.
Attribute markup extends the angular compiler in a very similar way to markup, except that it allows you to modify the state of attribute text rather then the content of a node.
angular.attrMarkup('extraClass', function(attrValue, attrName, element){ if (attrName == 'additional-class') { element.addClass(attrValue); } });