OLD | NEW |
| (Empty) |
1 --- | |
2 layout: default | |
3 title: "Use Templates" | |
4 description: "Use template loops and conditionals for declarative UI creation." | |
5 has-permalinks: true | |
6 tutorial: | |
7 id: web-ui-templates | |
8 next: custom-elements/ | |
9 next-title: "Define a Custom DOM Tag" | |
10 prev: web-ui/ | |
11 prev-title: "Get Started with Web UI" | |
12 --- | |
13 | |
14 {% capture whats_the_point %} | |
15 | |
16 * The Web UI package implements templates in HTML. | |
17 * You can conditionally activate DOM elements declaratively. | |
18 * Use template loops to create UI elements from a Dart Iterable. | |
19 | |
20 {% endcapture %} | |
21 | |
22 {% capture sample_links %} | |
23 | |
24 <p> | |
25 Get the source code for the samples featured in this target:</p> | |
26 | |
27 <ul> | |
28 <li> | |
29 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web
/target07/adlibitum" | |
30 target="_blank">adlibitum</a> | |
31 </li> | |
32 <li> | |
33 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web
/target07/simplehangman" | |
34 target="_blank">simplehangman</a> | |
35 </li> | |
36 <li> | |
37 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web
/target07/hangman" | |
38 target="_blank">hangman</a> | |
39 </li> | |
40 </ul> | |
41 | |
42 {% endcapture %} | |
43 | |
44 {% capture content %} | |
45 | |
46 <div class="tute-target-title"> | |
47 <h1>{{page.title}}</h1> | |
48 <h3>Create dynamic elements declaratively.</h3> | |
49 </div> | |
50 | |
51 <hr> | |
52 | |
53 <aside class="alert" style="background-color:Lavender;color:SlateBlue"> | |
54 <font size="24"> | |
55 <i class="icon-bullhorn"> </i> | |
56 </font> | |
57 Web UI is being upgraded to polymer.dart. | |
58 For more information about polymer.dart, | |
59 including tips on porting Web UI apps to polymer.dart | |
60 and the current status of the project, | |
61 check out the <a href="/polymer-dart/" target="_blank">polymer.dart</a> | |
62 home page. | |
63 For polymer.dart versions of the tutorial's Web UI apps, | |
64 check out the tutorial's | |
65 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/" | |
66 target="_blank">code repo</a> on github. | |
67 </aside> | |
68 | |
69 <hr> | |
70 | |
71 The Web UI package implements the <template> tag, | |
72 which you can use directly in your HTML. | |
73 Templates define UI elements that are instantiated | |
74 only under specific circumstances. | |
75 You can use templates to define the structure of a custom element, | |
76 to instantiate UI elements based on a boolean condition, | |
77 or to repeat UI elements by iterating over a Dart Iterable object. | |
78 | |
79 This target covers | |
80 template conditionals and loops, | |
81 both of which provide a declarative way | |
82 to add and remove UI elements. | |
83 The next target, | |
84 <a href="/docs/tutorials/custom-elements/">Target 8: Define a Custom DOM Tag</a>
, | |
85 covers custom elements | |
86 and how to use templates to define their structure. | |
87 | |
88 * [Using conditional instantiation](#using-conditional-instantiation) | |
89 * [Using iteration with templates](#using-iteration-with-templates) | |
90 * [Using iteration with other elements](#as-attributes) | |
91 * [Other resources](#other-resources) | |
92 | |
93 ##Using conditional instantiation | |
94 | |
95 In the example application running below, | |
96 you provide six words to fill in the blanks of a hidden text. | |
97 Try it! Type six items into the input fields. | |
98 The results appear only after you have entered a value for all six items. | |
99 After you've entered all six items, delete one. The paragraph disappears. | |
100 | |
101 <iframe class="running-app-frame" | |
102 style="height:300px;width:300px;" | |
103 src="http://dart-lang.github.io/dart-tutorials-samples/web/target07/adli
bitum/web/out/adlibitum.html"> | |
104 </iframe> | |
105 | |
106 You can find the complete source code for this sample on github at | |
107 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get07/adlibitum" target="_blank">adlibitum</a>. | |
108 | |
109 The sample uses a template conditional | |
110 to display the paragraphs under the input fields. | |
111 | |
112  | |
113 | |
114 The value of each input field is bound to an observable Dart String | |
115 using two-way data binding as described in the | |
116 <a href="/docs/tutorials/web-ui/">previous target</a>. | |
117 The binding keeps the value of each input field in sync with | |
118 the value of a Dart string as the user types. | |
119 | |
120  | |
121 | |
122 The paragraph underneath the six input fields appears | |
123 if all input fields have a value. | |
124 Together, a template conditional in the HTML code | |
125 and an observable boolean getter in the Dart code | |
126 determine when to display the paragraph. | |
127 The Dart code contains a getter called `show` | |
128 that returns true if all of the fields have a value | |
129 or false if one or more is empty. | |
130 Observables determine that `show` depends on the six strings, | |
131 and notify a change on `show` if any strings change. | |
132 | |
133  | |
134 | |
135 The template is declared with the <template> tag. | |
136 The template tag has an `instantiate` attribute, | |
137 which contains the expression | |
138 that determines whether the template should be activated or deactivated. | |
139 | |
140 The instantiate attribute takes the form `if exp`, | |
141 where `exp` is a valid Dart expression | |
142 that evaluates to either true or false. | |
143 In this example, | |
144 the expression is a call to a top-level getter. | |
145 When the expression is true, | |
146 the contents of the template are instantiated. | |
147 Otherwise, any elements that were previously instantiated | |
148 are removed from the DOM. | |
149 | |
150 In this example, | |
151 the conditional template just contains simple paragraph elements | |
152 in which some of the text is bound to the values in input fields. | |
153 | |
154 ##Using iteration with templates | |
155 | |
156 The sample running below | |
157 is a simplified version of the children's hangman game. | |
158 Try it! Type letters in the field to guess the word. | |
159 | |
160 <iframe class="running-app-frame" | |
161 style="height:250px;width:300px;" | |
162 src="http://dart-lang.github.io/dart-tutorials-samples/web/target07/simp
lehangman/web/out/simplehangman.html"> | |
163 </iframe> | |
164 | |
165 You can find the complete source code for this sample on github at | |
166 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get07/simplehangman" target="_blank">simplehangman</a>. | |
167 | |
168 The hangman example uses template iteration in two places: | |
169 to reveal the correctly guessed letters in the | |
170 hyphenated version of the hidden word | |
171 and to display the list of incorrectly guessed letters. | |
172 | |
173  | |
174 | |
175 The Dart code creates two lists, | |
176 one for the hyphenated word and one for the incorrectly guessed letters. | |
177 Each list contains strings. | |
178 Each string contains a single hyphen or letter. | |
179 The program calls `toObservable()` on each list | |
180 to make Web UI track changes to the list. | |
181 | |
182 {% prettify dart %} | |
183 List<String> hyphens = toObservable(answerHyphenated.split('')); | |
184 List<String> wrongletters = toObservable(new List()); | |
185 {% endprettify %} | |
186 | |
187 In the HTML code, | |
188 a template loop iterates over the list named `hyphens` | |
189 to reveal each letter of the word when it is correctly guessed. | |
190 Another template loop iterates over the list named `wrongletters` | |
191 to display the incorrectly guessed letters. | |
192 | |
193 {% prettify html %} | |
194 <template iterate="character in hyphens"> {% raw %}{{character}}{% endraw %} </t
emplate> | |
195 ... | |
196 <template iterate="wrongchar in wrongletters"> {% raw %}{{wrongchar}}{% endraw
%} </template> | |
197 {% endprettify %} | |
198 | |
199 When the user types a character, | |
200 the event handler for the input field either adds a letter to `wrongletters` | |
201 or reveals a letter in `hyphens`. | |
202 Because these lists are observable, | |
203 a change causes the associated template loop | |
204 to re-evaluate and to update the UI. | |
205 The following diagram shows the relationship between | |
206 the Dart code, the HTML code, and the UI | |
207 that manages the list of incorrectly guessed letters. | |
208 | |
209  | |
210 | |
211 The <template> tag has an attribute called `iterate`. | |
212 The value of this attribute takes the form | |
213 <code><em>loopvar</em> in <em>iterable</em></code>, | |
214 where _iterable_ is a Dart expression that evaluates to an | |
215 <a href="https://api.dartlang.org/dart_core/Iterable.html" | |
216 target="_blank">Iterable</a> | |
217 object. | |
218 The template iterates over the iterable object | |
219 and assigns each value to _loopvar_, | |
220 a new variable that is in scope for the body of the template iterate element. | |
221 The HTML code for this example | |
222 uses one-way data binding to embed | |
223 the value of `wrongchar` in the page, | |
224 thus displaying a list of characters. | |
225 | |
226 ##Using iteration with other elements {#as-attributes} | |
227 | |
228 The simplehangman example used the iterate attribute on a template node. | |
229 You can use `template iterate` as an attribute on any type of element. | |
230 This is particularly useful in tables | |
231 because you cannot use templates in tables. | |
232 In the future, the Web UI team intends to remove the extra `template` | |
233 attribute, and you will be able to use just `iterate` directly | |
234 on elements as well as on templates. | |
235 | |
236 Here's a new version of the hangman example. | |
237 Try it! Guess the word. | |
238 | |
239 <iframe class="running-app-frame" | |
240 style="height:250px;width:350px;" | |
241 src="http://dart-lang.github.io/dart-tutorials-samples/web/target07/hang
man/web/out/hangman.html"> | |
242 </iframe> | |
243 | |
244 You can find the complete source code for this sample on github at | |
245 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get07/hangman" target="_blank">hangman</a>. | |
246 | |
247 The gallows is displayed using a table. | |
248 The table uses `template iterate` as an attribute on | |
249 the table body and on the table row to | |
250 display the characters in the hangman display. | |
251 | |
252  | |
253 | |
254 The data for the gallows is contained on the Dart side | |
255 in a list of lists called `hangmandisplay`. | |
256 Each sublist is a list of strings, each of which | |
257 contains a single character. | |
258 So each string represents a cell in the table. | |
259 The top-level function setUpHangmanGrid() populates | |
260 the list of lists with this code: | |
261 | |
262 {% prettify dart %} | |
263 List<List> hangmandisplay; | |
264 | |
265 void setUpHangmanGrid() { | |
266 var gallows = [ '+---+ ', | |
267 '\| ', | |
268 '\| ', | |
269 '\| ', | |
270 '\| ' ]; | |
271 hangmandisplay = new List(gallows.length); | |
272 | |
273 for (int i = 0; i < gallows.length; i++) { | |
274 List<String> row = gallows[i].split(""); | |
275 hangmandisplay[i] = toObservable(row); | |
276 } | |
277 } | |
278 {% endprettify %} | |
279 | |
280 To create the table in HTML, | |
281 one template loop iterates over of the hangmandisplay list of lists, | |
282 using each sublist for a row in the table. | |
283 The second template loop iterates over each sublist (a list of strings) | |
284 using each string for a cell in the table. | |
285 | |
286  | |
287 | |
288 `hangmandisplay` is the Dart data to iterate over. | |
289 `row` and `cell` are both temporary loop variables. | |
290 | |
291 The contents of the hangmandisplay are changed programmatically | |
292 for each incorrectly guessed letter in a top-level function called | |
293 revealnewbodypart(). | |
294 | |
295 When the user guesses a letter, | |
296 the change event handler is called. | |
297 If the guess is incorrect, | |
298 the contents of the hangmandisplay are modified. | |
299 As a result of the change event, | |
300 the observables are re-evaluated and | |
301 the gallows UI is updated. | |
302 | |
303 ##Other resources | |
304 | |
305 <ul> | |
306 <li> | |
307 Another use of the <template> tag | |
308 is to define the contents of a custom element. | |
309 The next target, | |
310 <a href="/docs/tutorials/custom-elements/">Define a Custom DOM Tag</a>, | |
311 provides an example that converts numbers based on a simple ratio. | |
312 </li> | |
313 <li> Check out | |
314 <a href="/docs/cookbook/"> | |
315 <i class="icon-food"> </i> Dart Cookbook</a>. | |
316 You'll find several | |
317 <a href="/docs/cookbook/#web-ui">Web UI recipes</a>. | |
318 </li> | |
319 <li> | |
320 Sigmund Cherem's article, | |
321 <a href="/articles/dart-web-components/">Web UI Package</a>, | |
322 contains several interactive examples on the page | |
323 and the corresponding source code. | |
324 </li> | |
325 </ul> | |
326 | |
327 {% endcapture %} | |
328 | |
329 {% include tutorial.html %} | |
OLD | NEW |