2011-06-06 15:50:35 +00:00
|
|
|
@ngdoc overview
|
|
|
|
|
@name Developer Guide: Angular HTML Compiler: Extending the Angular Compiler
|
|
|
|
|
@description
|
|
|
|
|
|
|
|
|
|
Let's say that we want to create a new DOM element called `<my:greeter/>` that displays a greeting.
|
|
|
|
|
We want this HTML source:
|
|
|
|
|
|
|
|
|
|
<pre>
|
2011-06-16 05:32:24 +00:00
|
|
|
<div ng:init="s='Hello'; n='World'">
|
2011-07-29 19:45:10 +00:00
|
|
|
<my:greeter salutation="s" name="n"></my:greeter>
|
2011-06-16 05:32:24 +00:00
|
|
|
</div>
|
2011-06-06 15:50:35 +00:00
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
to produce this DOM:
|
|
|
|
|
|
|
|
|
|
<pre>
|
2011-06-16 05:32:24 +00:00
|
|
|
<div ng:init="s='Hello'; n='World'">
|
|
|
|
|
<my:greeter salutation="s" name="n"/>
|
2011-06-06 15:50:35 +00:00
|
|
|
<span class="salutation">Hello</span>
|
|
|
|
|
<span class="name">World</span>!
|
|
|
|
|
</my:greeter>
|
|
|
|
|
</div>
|
|
|
|
|
</pre>
|
|
|
|
|
|
2011-07-29 19:45:10 +00:00
|
|
|
That is, the new `<my:greeter></my:greeter>` tag's `salutation` and `name` attributes should be
|
|
|
|
|
transformed by the compiler such that two `<span>` tags display the values of the attributes, with
|
|
|
|
|
CSS classes applied to the output.
|
2011-06-06 15:50:35 +00:00
|
|
|
|
|
|
|
|
The following code snippet shows how to write a following widget definition that will be processed
|
|
|
|
|
by the compiler. Note that you have to declare the {@link dev_guide.bootstrap namespace} `my` in
|
|
|
|
|
the page:
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
angular.widget('my:greeter', function(compileElement){
|
2011-06-16 05:32:24 +00:00
|
|
|
var compiler = this;
|
|
|
|
|
compileElement.css('display', 'block');
|
|
|
|
|
var salutationExp = compileElement.attr('salutation');
|
|
|
|
|
var nameExp = compileElement.attr('name');
|
|
|
|
|
return function(linkElement){
|
|
|
|
|
var salutationSpan = angular.element('<span class="salutation"></span');
|
|
|
|
|
var nameSpan = angular.element('<span class="name"></span>');
|
|
|
|
|
linkElement.append(salutationSpan);
|
2011-07-29 19:45:10 +00:00
|
|
|
linkElement.append(' ');
|
2011-06-16 05:32:24 +00:00
|
|
|
linkElement.append(nameSpan);
|
2011-07-29 19:45:10 +00:00
|
|
|
linkElement.append('!');
|
2011-06-16 05:32:24 +00:00
|
|
|
this.$watch(salutationExp, function(value){
|
|
|
|
|
salutationSpan.text(value);
|
|
|
|
|
});
|
|
|
|
|
this.$watch(nameExp, function(value){
|
|
|
|
|
nameSpan.text(value);
|
|
|
|
|
});
|
|
|
|
|
};
|
2011-06-06 15:50:35 +00:00
|
|
|
});
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note: For more about widgets, see {@link dev_guide.compiler.widgets Understanding Angular Widgets}
|
|
|
|
|
and the {@link api/angular.widget widget API reference page}.
|
|
|
|
|
|
|
|
|
|
# Compilation process for `<my:greeter>`
|
|
|
|
|
|
|
|
|
|
Here are the steps that the compiler takes in processing the page that contains the widget
|
|
|
|
|
definition above:
|
|
|
|
|
|
|
|
|
|
## Compile Phase
|
|
|
|
|
|
|
|
|
|
1. Recursively traverse the DOM depth-first.
|
|
|
|
|
2. Find the angular.widget definition.
|
|
|
|
|
3. Find and execute the widget's compileElement function, which includes the following steps:
|
|
|
|
|
1. Add a style element with attribute display: block; to the template DOM so that the browser
|
|
|
|
|
knows to treat the element as block element for rendering. (Note: because this style element was
|
|
|
|
|
added on the template compileElement, this style is automatically applied to any clones of the
|
|
|
|
|
template (i.e. any repeating elements)).
|
|
|
|
|
2. Extract the salutation and name HTML attributes as angular expressions.
|
|
|
|
|
4. Return the aggregate link function, which includes just one link function in this example.
|
|
|
|
|
|
|
|
|
|
## Link Phase
|
|
|
|
|
|
|
|
|
|
1. Execute the aggregate link function, which includes the following steps:
|
|
|
|
|
1. Create a <span> element set to the salutation class
|
|
|
|
|
2. Create a <span> element set to the name class.
|
|
|
|
|
2. Add the span elements to the linkElement. (Note: be careful not to add them to the
|
|
|
|
|
compileElement, because that's the template.)
|
|
|
|
|
3. Set up watches on the expressions. When an expression changes, copy the data to the
|
|
|
|
|
corresponding spans.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Related Topics
|
|
|
|
|
|
|
|
|
|
* {@link dev_guide.compiler Angular HTML Compiler}
|
|
|
|
|
* {@link dev_guide.compiler.understanding_compiler Understanding How the Compiler Works}
|
|
|
|
|
* {@link dev_guide.compiler.testing_dom_element Testing a New DOM Element}
|
|
|
|
|
|
|
|
|
|
## Related API
|
|
|
|
|
|
2011-11-12 01:15:22 +00:00
|
|
|
* {@link api/angular.module.ng.$compile $compile()}
|