forked from angular/code.angularjs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdev_guide.compiler.extending_compiler.html
89 lines (78 loc) · 4.31 KB
/
dev_guide.compiler.extending_compiler.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<h1>Developer Guide: Angular HTML Compiler: Extending the Angular Compiler</h1>
<div class="developer-guide-angular-html-compiler-extending-the-angular-compiler"><fieldset class="workInProgress"><legend>Work in Progress</legend>
This page is currently being revised. It might be incomplete or contain inaccuracies.</fieldset>
<p>Let's say that we want to create a new DOM element called <code><my:greeter/></code> that displays a greeting.
We want this HTML source:</p><div ng:non-bindable><pre class="brush: js; html-script: true;">
<div ng:init="s='Hello'; n='World'">
<my:greeter salutation="s" name="n"></my:greeter>
</div>
</pre></div><p>to produce this DOM:</p><div ng:non-bindable><pre class="brush: js; html-script: true;">
<div ng:init="s='Hello'; n='World'">
<my:greeter salutation="s" name="n"/>
<span class="salutation">Hello</span>
<span class="name">World</span>!
</my:greeter>
</div>
</pre></div><p>That is, the new <code><my:greeter></my:greeter></code> tag's <code>salutation</code> and <code>name</code> attributes should be
transformed by the compiler such that two <code><span></code> tags display the values of the attributes, with
CSS classes applied to the output.</p>
<p>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 <a href="#!/guide/dev_guide.bootstrap">namespace</a> <code>my</code> in
the page:</p><div ng:non-bindable><pre class="brush: js; html-script: true;">
angular.widget('my:greeter', function(compileElement){
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);
linkElement.append(' ');
linkElement.append(nameSpan);
linkElement.append('!');
this.$watch(salutationExp, function(value){
salutationSpan.text(value);
});
this.$watch(nameExp, function(value){
nameSpan.text(value);
});
};
});
</pre></div><p>Note: For more about widgets, see <a href="#!/guide/dev_guide.compiler.widgets">Understanding Angular Widgets</a>
and the <a href="#!/api/angular.widget"><code>widget API reference page</code></a>.</p>
<h2>Compilation process for <code><my:greeter></code></h2>
<p>Here are the steps that the compiler takes in processing the page that contains the widget
definition above:</p>
<h3>Compile Phase</h3>
<ol>
<li>Recursively traverse the DOM depth-first.</li>
<li>Find the angular.widget definition.</li>
<li>Find and execute the widget's compileElement function, which includes the following steps:
<ol><li>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)).</li>
<li>Extract the salutation and name HTML attributes as angular expressions.</li></ol></li>
<li>Return the aggregate link function, which includes just one link function in this example.</li>
</ol>
<h3>Link Phase</h3>
<ol>
<li>Execute the aggregate link function, which includes the following steps:
<ol><li>Create a <span> element set to the salutation class</li>
<li>Create a <span> element set to the name class.</li></ol></li>
<li>Add the span elements to the linkElement. (Note: be careful not to add them to the
compileElement, because that's the template.)</li>
<li>Set up watches on the expressions. When an expression changes, copy the data to the
corresponding spans.</li>
</ol>
<h3>Related Topics</h3>
<ul>
<li><a href="#!/guide/dev_guide.compiler">Angular HTML Compiler</a></li>
<li><a href="#!/guide/dev_guide.compiler.understanding_compiler">Understanding How the Compiler Works</a></li>
<li><a href="#!/guide/dev_guide.compiler.testing_dom_element">Testing a New DOM Element</a></li>
</ul>
<h3>Related API</h3>
<ul>
<li><a href="#!/api/angular.compile"><code>angular.compile()</code></a></li>
</ul></div>