Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
html formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb committed Feb 16, 2014
1 parent 4221c16 commit 84a49fd
Showing 1 changed file with 72 additions and 75 deletions.
147 changes: 72 additions & 75 deletions app/tutorial/06-ch04-directive.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,34 +118,39 @@ <h1 id="angulardart-tutorial-creating-a-custom-directive">Creating a Custom Dire

<hr />

<p>Directives offer a way to define behavior that can be triggered using CSS selectors—most commonly, element attributes. Each element can have multiple directives, just as it can have multiple HTML attributes.
If you are familiar with the <a href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator design pattern</a>, then you can think of a directive as an <em>HTML element decorator</em>.</p>
<p>Directives offer a way to define behavior that can be triggered using CSS selectors—most
commonly, element attributes. Each element can have multiple directives, just as it can have
multiple HTML attributes. If you are familiar with the
<a href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator design pattern</a>, then
you can think of a directive as an <em>HTML element decorator</em>.</p>

<p>This chapter defines a directive called <em>tooltip</em>. HTML code can use the tooltip directive in a span or any other element:</p>
<p>This chapter defines a directive called <em>tooltip</em>. HTML code can use the tooltip
directive in a span or any other element:</p>

<pre class="prettyprint"><code>&lt;span tooltip="ctrl.tooltipForRecipe(recipe)"&gt;
...
&lt;/span&gt;
</code></pre>

<p><strong>Note:</strong>
The NgDirective annotation can also be used to create structural directives,
such as the built-in ng-if and ng-repeat directives.
This is an advanced usage case, and we don’t cover it.</p>
<p><strong>Note:</strong> The <code>NgDirective</code> annotation can also be used to create
structural directives, such as the built-in <code>ng-if</code> and <code>ng-repeat</code>
directives. This is an advanced usage case, and we don’t cover it.</p>

<hr class="spacer" />

<h3 id="running-the-sample-app">Running the sample app</h3>
<p>The code for this chapter is in the
<em><a href="https://github.com/angular/angular.dart.tutorial/tree/master/Chapter_04">Chapter_04</a></em> directory of the
<a href="https://github.com/angular/angular.dart.tutorial/archive/master.zip">angular.dart.tutorial download</a>.
View it in Dart Editor by using <strong>File &gt; Open Existing Folder...</strong>
to open the <strong>Chapter_04</strong> directory. </p>
<em><a href="https://github.com/angular/angular.dart.tutorial/tree/master/Chapter_04">Chapter_04</a>
</em> directory of the
<a href="https://github.com/angular/angular.dart.tutorial/archive/master.zip">angular.dart.tutorial
download</a>. View it in Dart Editor by using <strong>File &gt; Open Existing Folder...</strong>
to open the <strong>Chapter_04</strong> directory.</p>

<p>Now run the app. In Dart Editor’s Files view, select <strong>Chapter_04/web/index.html</strong>, right-click, and choose <strong>Run in Dartium</strong>.</p>
<p>Now run the app. In Dart Editor’s Files view, select
<strong>Chapter_04/web/index.html</strong>, right-click, and choose <strong>Run in Dartium</strong>.
</p>

<p>See how mousing over any item in the recipe list
brings up a tooltip for that recipe. </p>
<p>See how mousing over any item in the recipe list brings up a tooltip for that recipe.</p>

<hr class="spacer" />

Expand All @@ -154,28 +159,28 @@ <h3 id="custom-directives">Custom directives</h3>
<p>Implementing the tooltip required changing the code in the following ways:</p>

<ul>
<li>Adding two classes: Tooltip implements the directive,
and TooltipModel encapsulates its data.</li>
<li>Modifying the controller (RecipeBookController)
so that it adds an image for each recipe and creates tooltip models.</li>
<li>Modifying <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/web/main.dart">web/main.dart</a>
to register the Tooltip type.</li>
<li>Modifying <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/web/index.html">web/index.html</a>
to use the tooltip directive.</li>
<li>Adding two classes: Tooltip implements the directive, and TooltipModel encapsulates
its data.</li>
<li>Modifying the controller (RecipeBookController) so that it adds an image for each
recipe and creates tooltip models.</li>
<li>Modifying <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/web/main.dart">
web/main.dart</a> to register the Tooltip type.</li>
<li>Modifying <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/web/index.html">
web/index.html</a> to use the tooltip directive.</li>
</ul>

<hr class="spacer" />

<h3 id="implementing-a-directive">Implementing a directive</h3>

<p>The @NgDirective and @NgOneWay annotations specify the tooltip API:</p>
<p>The <code>@NgDirective</code> and <code>@NgOneWay</code> annotations specify the
tooltip API:</p>

<pre class="prettyprint">...
import 'package:angular/angular.dart';

@NgDirective(
selector: '[tooltip]'
)
selector: '[tooltip]')
class Tooltip {
dom.Element element;

Expand All @@ -190,30 +195,25 @@ <h3 id="implementing-a-directive">Implementing a directive</h3>
</pre>

<p>The <strong>selector</strong> argument to the NgDirective constructor specifies
when a Tooltip object should be instantiated:
whenever an element has an attribute named “tooltip”.
The @NgOneWay annotation specifies that
the value of the tooltip attribute is bound to
the <code>displayModel</code> field in Tooltip.</p>
when a Tooltip object should be instantiated: whenever an element has an attribute
named “tooltip”. The <code>@NgOneWay</code> annotation specifies that the value of
the tooltip attribute is bound to the <code>displayModel</code> field in Tooltip.</p>

<p>Consider the following HTML:</p>

<pre class="prettyprint">&lt;span tooltip="ctrl.tooltipForRecipe(recipe)"&gt;
</pre>

<p>Along with the preceding Dart code,
this HTML tells AngularDart to create a Tooltip object and
sets its <code>displayModel</code> field to the value returned by
<code>ctrl.tooltipForRecipe(recipe)</code>.
The Tooltip constructor is passed a single argument,
an Element representing the <code>&lt;span&gt;</code>.</p>
<p>Along with the preceding Dart code, this HTML tells AngularDart to create a Tooltip
object and sets its <code>displayModel</code> field to the value returned by <code>
ctrl.tooltipForRecipe(recipe)</code>. The Tooltip constructor is passed a single argument,
an Element representing the <code>&lt;span&gt;</code>.</p>

<p>In general, when you want to implement a directive as an attribute that
takes a value, do it like this:</p>
<p>In general, when you want to implement a directive as an attribute that takes a
value, do it like this:</p>

<pre class="prettyprint">@NgDirective(
selector: '[attributeName]'
)
selector: '[attributeName]')
class MyDirective {
@NgOneWay('attributeName')
Model model;
Expand All @@ -224,16 +224,14 @@ <h3 id="implementing-a-directive">Implementing a directive</h3>
...
}</pre>

<p>AngularDart’s dependency injection system calls the constructor,
supplying context-specific objects for
whatever arguments the constructor declares.</p>
<p>AngularDart’s dependency injection system calls the constructor, supplying
context-specific objects for whatever arguments the constructor declares.</p>

<p>Back to the Tooltip implementation,
most of its code is devoted to creating a <code>&lt;div&gt;</code>
and children to display the tooltip,
and then appending the <code>&lt;div&gt;</code> to the DOM.
Here’s the code that creates and appends the <code>&lt;div&gt;</code> (<code>tooltipElem</code>)
whenever the user mouses over an element that has a tooltip:</p>
<p>Back to the Tooltip implementation, most of its code is devoted to creating
a <code>&lt;div&gt;</code> and children to display the tooltip, and then
appending the <code>&lt;div&gt;</code> to the DOM. Here’s the code that creates
and appends the <code>&lt;div&gt;</code> (<code>tooltipElem</code>) whenever the
user mouses over an element that has a tooltip:</p>

<pre class="prettyprint">import 'dart:html' as dom;
...
Expand All @@ -245,29 +243,28 @@ <h3 id="implementing-a-directive">Implementing a directive</h3>

dom.document.body.append(tooltipElem);</pre>

<p><strong>Important:</strong>
Because Angular expects to have full control of the DOM,
be careful if you dynamically create HTML elements.</p>
<p><strong>Important:</strong> Because Angular expects to have full control of
the DOM, be careful if you dynamically create HTML elements.</p>

<p>Here are the rules for manipulating DOM elements in directives:</p>

<ul>
<li>If changing the DOM structure (adding/removing/moving nodes),
do so only <em>outside</em> of the directive’s constructor.
(Modifying node properties, on the other hand,
is OK inside the constructor or at any other time.) </li>
<li>If changing the DOM structure (adding/removing/moving nodes), do so only
<em>outside</em> of the directive’s constructor. (Modifying node properties,
on the other hand, is OK inside the constructor or at any other time.) </li>
<li>Don’t destroy elements that AngularDart is managing.</li>
</ul>

<p>In this case, adding the tooltip’s <code>&lt;div&gt;</code> element is OK because
the new element (1) is appended to the <code>&lt;body&gt;</code> and
(2) is added outside the constructor.</p>
<p>In this case, adding the tooltip’s <code>&lt;div&gt;</code> element is OK
because the new element (1) is appended to the <code>&lt;body&gt;</code> and
(2) is added outside the constructor.</p>

<p>You can see all the code to create, position, and destroy tooltips in
<a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/lib/tooltip/tooltip_directive.dart">lib/tooltip/tooltip_directive.dart</a>.</p>
<a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/lib/tooltip/tooltip_directive.dart">
lib/tooltip/tooltip_directive.dart</a>.</p>

<p>The implementation of the TooltipModel class is trivial.
The class just encapsulates data that the tooltip needs:</p>
<p>The implementation of the TooltipModel class is trivial. The class just
encapsulates data that the tooltip needs:</p>

<pre class="prettyprint">class TooltipModel {
String imgUrl;
Expand All @@ -280,15 +277,16 @@ <h3 id="implementing-a-directive">Implementing a directive</h3>

<hr class="spacer" />

<h3 id="modifying-the-controller-to-provide-the-model">Modifying the controller to provide the model</h3>
<h3 id="modifying-the-controller-to-provide-the-model">Modifying the controller
to provide the model</h3>

<p>Remember that we want the HTML to be able to use a tooltip directive like this:</p>

<pre class="prettyprint">&lt;span tooltip="ctrl.tooltipForRecipe(recipe)"&gt;</pre>

<p>That means the controller needs to implement <code>tooltipForRecipe(Recipe)</code>.
The tooltip directive expects a TooltipModel argument,
so that’s the type that tooltipForRecipe() returns.</p>
The tooltip directive expects a TooltipModel argument, so that’s the type that
<code>tooltipForRecipe()</code> returns.</p>

<pre class="prettyprint">class RecipeBookController {
...
Expand All @@ -304,21 +302,20 @@ <h3 id="modifying-the-controller-to-provide-the-model">Modifying the controller
}</pre>

<p>The use of <a href="https://api.dartlang.org/dart_core/Expando.html">Expando</a>
is an implementation detail.
An Expando is just a way to associate a property
(in this case, a TooltipModel) with an existing object (a recipe).
Instead of an Expando, the code could use a mixin,
a TooltipModel subclass, or a map.</p>
is an implementation detail. An Expando is just a way to associate a property
(in this case, a TooltipModel) with an existing object (a recipe). Instead of an
Expando, the code could use a mixin, a TooltipModel subclass, or a map.</p>

<p>The other changes to <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/lib/recipe_book.dart">lib/recipe_book.dart</a>
include adding an <code>imgUrl</code> field to the Recipe class.</p>
<p>The other changes to <a href="https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_04/lib/recipe_book.dart">
lib/recipe_book.dart</a> include adding an <code>imgUrl</code> field to the Recipe
class.</p>

<hr class="spacer" />

<h3 id="table-angular-annotations">Table: Angular annotations</h3>
<p>The Recipe Book app now uses all three of Angular’s annotation classes.
The following table summarizes how you typically use these annotations,
and whether they create a new scope.</p>
<p>The Recipe Book app now uses all three of Angular’s annotation classes. The
following table summarizes how you typically use these annotations, and whether
they create a new scope.</p>

<table>
<tr>
Expand Down

0 comments on commit 84a49fd

Please sign in to comment.