142 lines
7.2 KiB
HTML
Executable file
142 lines
7.2 KiB
HTML
Executable file
<h1><code ng:non-bindable=""></code>
|
|
<span class="hint"></span>
|
|
</h1>
|
|
<div><a href="http://github.com/angular/angular.js/edit/master/docs/content/guide/compiler.ngdoc" class="improve-docs btn btn-primary">Improve this doc</a><h2>Overview</h2>
|
|
|
|
<p>Angular's <a href="api/ng.$compile"><code>HTML compiler</code></a> allows the developer to teach the
|
|
browser new HTML syntax. The compiler allows you to attach behavior to any HTML element or attribute
|
|
and even create new HTML element or attributes with custom behavior. Angular calls these behavior
|
|
extensions <a href="api/ng.$compileProvider#directive"><code>directives</code></a>.</p>
|
|
|
|
<p>HTML has a lot of constructs for formatting the HTML for static documents in a declarative fashion.
|
|
For example if something needs to be centered, there is no need to provide instructions to the
|
|
browser how the window size needs to be divided in half so that center is found, and that this
|
|
center needs to be aligned with the text's center. Simply add <code>align="center"</code> attribute to any
|
|
element to achieve the desired behavior. Such is the power of declarative language.</p>
|
|
|
|
<p>But the declarative language is also limited, since it does not allow you to teach the browser new
|
|
syntax. For example there is no easy way to get the browser to align the text at 1/3 the position
|
|
instead of 1/2. What is needed is a way to teach browser new HTML syntax.</p>
|
|
|
|
<p>Angular comes pre-bundled with common directives which are useful for building any app. We also
|
|
expect that you will create directives that are specific to your app. These extension become a
|
|
Domain Specific Language for building your application.</p>
|
|
|
|
<p>All of this compilation takes place in the web browser; no server side or pre-compilation step is
|
|
involved.</p>
|
|
|
|
<h2>Compiler</h2>
|
|
|
|
<p>Compiler is an angular service which traverses the DOM looking for attributes. The compilation
|
|
process happens into two phases.</p>
|
|
|
|
<ol>
|
|
<li><p><strong>Compile:</strong> traverse the DOM and collect all of the directives. The result is a linking
|
|
function.</p></li>
|
|
<li><p><strong>Link:</strong> combine the directives with a scope and produce a live view. Any changes in the
|
|
scope model are reflected in the view, and any user interactions with the view are reflected
|
|
in the scope model. This makes the scope model the single source of truth.</p></li>
|
|
</ol>
|
|
|
|
<p>Some directives such <a href="api/ng.directive:ngRepeat"><code><code>ng-repeat</code></code></a> clone DOM elements once for each item in collection. Having a compile and link phase
|
|
improves performance since the cloned template only needs to be compiled once, and then linked
|
|
once for each clone instance.</p>
|
|
|
|
<h2>Directive</h2>
|
|
|
|
<p>A directive is a behavior which should be triggered when specific HTML constructs are encountered in
|
|
the compilation process. The directives can be placed in element names, attributes, class names, as
|
|
well as comments. Here are some equivalent examples of invoking the <a href="api/ng.directive:ngBind"><code><code>ng-bind</code></code></a> directive.</p>
|
|
|
|
<pre class="prettyprint linenums">
|
|
<span ng-bind="exp"></span>
|
|
<span class="ng-bind: exp;"></span>
|
|
<ng-bind></ng-bind>
|
|
<!-- directive: ng-bind exp -->
|
|
</pre>
|
|
|
|
<p>A directive is just a function which executes when the compiler encounters it in the DOM. See <a href="api/ng.$compileProvider#directive"><code>directive API</code></a> for in-depth documentation on how
|
|
to write directives.</p>
|
|
|
|
<p>Here is a directive which makes any element draggable. Notice the <code>draggable</code> attribute on the
|
|
<code><span></code> element.</p>
|
|
|
|
<h3>Source</h3>
|
|
<div source-edit="drag" source-edit-deps="angular.js script.js" source-edit-html="index.html-16" source-edit-css="" source-edit-js="script.js-15" source-edit-unit="" source-edit-scenario=""></div>
|
|
<div class="tabbable"><div class="tab-pane" title="index.html">
|
|
<pre class="prettyprint linenums" ng-set-text="index.html-16" ng-html-wrap="drag angular.js script.js"></pre>
|
|
<script type="text/ng-template" id="index.html-16">
|
|
<span draggable>Drag ME</span>
|
|
</script>
|
|
</div>
|
|
<div class="tab-pane" title="script.js">
|
|
<pre class="prettyprint linenums" ng-set-text="script.js-15"></pre>
|
|
<script type="text/ng-template" id="script.js-15">
|
|
angular.module('drag', []).
|
|
directive('draggable', function($document) {
|
|
var startX=0, startY=0, x = 0, y = 0;
|
|
return function(scope, element, attr) {
|
|
element.css({
|
|
position: 'relative',
|
|
border: '1px solid red',
|
|
backgroundColor: 'lightgrey',
|
|
cursor: 'pointer'
|
|
});
|
|
element.bind('mousedown', function(event) {
|
|
startX = event.screenX - x;
|
|
startY = event.screenY - y;
|
|
$document.bind('mousemove', mousemove);
|
|
$document.bind('mouseup', mouseup);
|
|
});
|
|
|
|
function mousemove(event) {
|
|
y = event.screenY - startY;
|
|
x = event.screenX - startX;
|
|
element.css({
|
|
top: y + 'px',
|
|
left: x + 'px'
|
|
});
|
|
}
|
|
|
|
function mouseup() {
|
|
$document.unbind('mousemove', mousemove);
|
|
$document.unbind('mouseup', mouseup);
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</div>
|
|
</div><h3>Demo</h3>
|
|
<div class="well doc-example-live animator-container" ng-embed-app="drag" ng-set-html="index.html-16" ng-eval-javascript="script.js-15"></div>
|
|
|
|
<p>The presence of the <code>draggable</code> attribute on any element gives the element new behavior. The beauty of
|
|
this approach is that we have taught the browser a new trick. We have extended the vocabulary of
|
|
what the browser understands in a way which is natural to anyone who is familiar with HTML
|
|
principles.</p>
|
|
|
|
<h2>Understanding View</h2>
|
|
|
|
<p>There are many templating systems out there. Most of them consume a static string template and
|
|
combine it with data, resulting in a new string. The resulting text is then <code>innerHTML</code>ed into
|
|
an element.</p>
|
|
|
|
<p><img src="img/One_Way_Data_Binding.png"></p>
|
|
|
|
<p>This means that any changes to the data need to be re-merged with the template and then
|
|
<code>innerHTML</code>ed into the DOM. Some of the issues with this approach are: reading user input and merging it with data,
|
|
clobbering user input by overwriting it, managing the whole update process, and lack of behavior
|
|
expressiveness.</p>
|
|
|
|
<p>Angular is different. The Angular compiler consumes the DOM with directives, not string templates.
|
|
The result is a linking function, which when combined with a scope model results in a live view. The
|
|
view and scope model bindings are transparent. No action from the developer is needed to update
|
|
the view. And because no <code>innerHTML</code> is used there are no issues of clobbering user input.
|
|
Furthermore, Angular directives can contain not just text bindings, but behavioral constructs as
|
|
well.</p>
|
|
|
|
<p><img src="img/Two_Way_Data_Binding.png"></p>
|
|
|
|
<p>The Angular approach produces a stable DOM. This means that the DOM element instance bound to a model
|
|
item instance does not change for the lifetime of the binding. This means that the code can get
|
|
hold of the elements and register event handlers and know that the reference will not be destroyed
|
|
by template data merge.</p></div>
|