Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/site/docs/tutorials/polymer/index.markdown

Issue 24269013: first draft of polymer element tutorial (Closed) Base URL: https://github.com/dart-lang/dartlang.org.git@master
Patch Set: resolving some xx's Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/site/docs/tutorials/polymer/images/template-code.png ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 ---
2 layout: default
3 title: "Polymer Elements"
4 description: "Use Polymer elements to encapsulate and share custom DOM elements. "
5 has-permalinks: true
6 tutorial:
7 id: polymer-intro
8 next: fetchdata
9 next-title: "Fetch Data Dynamically"
10 prev: custom-elements
11 prev-title: "Define a Custom DOM Tag"
ericbidelman 2013/09/24 18:18:42 "Define a Custom HTML Element"
mem 2013/10/01 16:05:31 Done.
12 ---
13
14 {% capture whats_the_point %}
15
16 * Polymer.dart is the next evolution of Web UI.
17 * Everything in Polymer.dart is an element.
18 * Polymer elements provide semantically meaningful encapsulation.
19 * Use Polymer.dart to build custom tags.
20 * Bind Dart data to HTML elements.
21 * Declaratively bind event handlers to elements.
22
23 {% endcapture %}
24
25 {% capture sample_links %}
26
27 <p>
28 Get the source code for the samples featured in this target:</p>
29
30 <ul>
31 <li>
32 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web /target06-polymer/stopwatch"
33 target="_blank">stopwatch</a>
34 </li>
35 </ul>
36
37 {% endcapture %}
38
39 {% capture content %}
40
41 <div class="tute-target-title">
42 <h1>{{page.title}}</h1>
43 <h3>Create new HTML tags with Polymer elements</h3>
44 </div>
45
46 Polymer elements are one feature of the
47 <a href="http://www.polymer-project.org/">Polymer</a> project,
48 whose primary aim is to help manage the complexity
sethladd 2013/09/20 23:18:36 This sounds like we're speaking for polymer projec
Jennifer Messerly 2013/09/24 02:36:39 borrow some language from "Guiding principals" on
mem 2013/10/01 16:05:31 I got this language from their website. Changed it
49 of building web applications.
50 <a href="http://www.dartlang.org/polymer-dart/">Polymer.dart</a>
51 is the Dart implementation of Polymer.
52
53 A Polymer element is a customized element you can define yourself,
54 encapsulating appearance and/or behavior within semantically meaningful DOM tags .
ericbidelman 2013/09/24 18:18:42 DOM tags -> HTML elements
mem 2013/10/01 16:05:31 Done.
55
56 * [An example](#an-example)
57 * [Installing Polymer.dart](#getting-polymer-dart)
58 * [Including Polymer.dart in your application](#bootstrap)
59 * [Instantiating a Polymer element](#instantiating)
60 * [Defining a Polymer element](#define-element)
61 * [Providing a template for the Polymer element](#providing-a-template)
62 * [Providing a script for the Polymer element](#providing-a-script)
63 * [Overiding life-cycle methods](#life-cycle-methods)
64 * [Embedding live data on the page](#one-way-data-binding)
65 * [Setting up event handlers declaratively](#event-handlers)
66 * [Querying the shadow DOM](#in-the-shadows)
67 * [Styling a Polymer element](#scoped-css)
68 * [Other resources](#other-resources)
69
70 ##An example
71
72 In the example running below,
ericbidelman 2013/09/24 18:18:42 is a custom element, implemented using Polymer.
mem 2013/10/01 16:05:31 Done.
73 the area within the black rectangle is implemented by a Polymer element,
sethladd 2013/09/20 23:18:36 there are two black rectangles
mem 2013/10/01 16:05:31 Done.
74
75 <strong>Try it!</strong>
Jennifer Messerly 2013/09/24 02:36:39 FYI -- the example didn't work for me, but it work
mem 2013/10/01 16:05:31 The link here is actually the Web UI version of th
76 Start and stop the stopwatch.
77 Reset the stopwatch to 00:00 using the **Reset** button.
78
79 <iframe class="running-app-frame"
80 style="height:175px;width:202px;"
81 src="http://dart-lang.github.com/dart-tutorials-samples/web/target06/sto pwatch/web/out/stopwatch.html">
82 </iframe>
83
84 To place this Polymer element on an HTML page, you write:
sethladd 2013/09/20 23:18:36 you also need to import it
mem 2013/10/01 16:05:31 Done.
85
86 {% prettify html %}
87 <tute-stopwatch></tute-stopwatch>
88 {% endprettify %}
89
90 The counting text, the three buttons along with their actions,
91 and the style are all contained within the Polymer element.
92 The definition of the Polymer element encapsulates and
93 hides the implementation details,
94 which as the user of the element, you care nothing about.
95
96 When you use tools to inspect the element,
97 you see just the Polymer element's begin and end tag.
98 The contents of the Polymer element are hidden in the *shadow DOM*.
sethladd 2013/09/20 23:18:36 define shadow dom here, or omit because you don't
mem 2013/10/01 16:05:31 Done.
99
100 ![Polymer element encapsulates its contents](images/dev-tools-dom.png)
101
102 With Polymer elements, developers can easily create elements
103 with semantically meaningful tags that are easy to share,
104 re-use, and read.
105
106 ###Overview of the example files
107
108 Three primary source files implement the stopwatch example:
109
110 <dl>
111 <dt>
112 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web /target06-polymer/stopwatch/web/index.html" target="_blank">index.html</a>
113 </dt>
114 <dd>
115 The primary HTML file for the app.
116 Includes the Polymer bootstrap script and instantiates the Polymer element.
117 </dd>
118 <dt>
119 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web /target06-polymer/stopwatch/web/tute_stopwatch.html" target="_blank">tute_stopwa tch.html</a>
120 </dt>
121 <dd>
122 The HTML code that defines the Polymer element.
123 </dd>
124 <dt>
125 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web /target06-polymer/stopwatch/web/tute_stopwatch.dart" target="_blank">tute_stopwa tch.dart</a>
126 </dt>
127 <dd>
128 The Dart class that implements the Polymer element.
129 </dd>
130 </dl>
131
132 The following diagram shows the structure of the example
133 app and its use of Polymer elements.
ericbidelman 2013/09/24 18:18:42 There's a lot mentions of "Polymer elements", but
mem 2013/10/01 16:05:31 Changed Polymer elements -> custom elements everyw
134
135 ![The connections between Dart and HTML](images/connections.png)
136
137 ##Installing Polymer.dart {#getting-polymer-dart}
138
139 To use the features provided by Polymer.dart,
140 you need to install the polymer package.
141 If you are unfamiliar with installing packages,
142 refer to
143 <a href="/docs/tutorials/shared-pkgs/">Install Shared Packages</a>,
144 which describes the process in detail.
145
146 In brief, to install the polymer package:
147
148 * In the application's `pubspec.yaml` file,
149 add the package to the list of dependencies
150 by adding the package name, `polymer`, to the list.
151 YAML is whitespace-sensitive
152 so take care to indent the package name as shown:
153
154 ![Sample pubspec file with polymer dependency](images/sample-pubspec.png)
155
156 * If you are using Dart Editor,
157 when you save pubspec.yaml
158 the editor automatically runs `pub install`.
159 If you are using command line tools,
160 you can run it with the command `pub install`.
161 The installation process
162 recursively installs the polymer.dart package
163 and all the packages that it depends on.
164
165 ##Including Polymer.dart in your application {#bootstrap}
166
167 To use Polymer.dart features, such as Polymer elements,
168 you need to include Polymer in both
169 the HTML side and in the Dart side of your app.
170
171 * In the primary HTML file for your app,
172 you must include `packages/polymer/boot.js`
173 in the &lt;head&gt; section.
174 When using this script,
175 you do not need to include a top-level `main()` function,
176 although you may.
177 **Note:** Use this script in lieu of `packages/browser/dart.js`.
sethladd 2013/09/20 23:18:36 concerned that in lieu will be difficult for non-e
mem 2013/10/01 16:05:31 Done.
178
179 ![Include the Polymer bootstrap script](images/bootstrap-script.png)
180
181 * Each Dart file that uses Polymer features
182 needs to import the Polymer library:
183
184 ![Import the Polymer library](images/polymer-library.png)
185
186 ##Instantiating a Polymer element {#instantiating}
187
188 To create an instance of the Polymer element,
189 use the name of the Polymer element just as you would any normal HTML tag.
190 In this example, the tag name is `tute-stopwatch`.
191
192 ![Instantiate a Polymer element with a custom tag](images/polymer-element-instan tiation.png)
193
194 Using best practices,
195 the Polymer element definition is in a separate file.
196 Use `link` to import the HTML definition file as shown.
ericbidelman 2013/09/24 18:18:42 `link[rel="import"]` to be clear
mem 2013/10/01 16:05:31 Done.
197
198 ##Defining a Polymer element {#define-element}
199
200 The definition for the tute-stopwatch element is
ericbidelman 2013/09/24 18:18:42 <tute-stopwatch>
mem 2013/10/01 16:05:31 Done.
201 in `tute-stopwatch.html`.
sethladd 2013/09/20 23:18:36 use underscore instead of dash
mem 2013/10/01 16:05:31 Done.
202 A Polymer element definition should be in its own
203 source file so that it can be included by other files.
204 An HTML file that contains a Polymer element definition
205 does not need &lt;html&gt;, &lt;head&gt;, or &lt;body&gt; tags.
206
207 To define a Polymer element,
208 use the &lt;polymer-element&gt; tag and provide a name.
209
210 {% prettify html %}
211 <polymer-element name="tute-stopwatch">
212 ...
213 </polymer-element>
214 {% endprettify %}
215
216 A Polymer element name must have at least one hyphen (`-`).
217 We advise using an identifiable prefix to
218 avoid naming conflicts with elements shared by others
219 and to help identify the project from which the element originates.
220 For example, for tutorial polymer elements, we use the prefix `tute`.
221
222 Within the &lt;polymer-element&gt; tag,
223 you can provide a template (appearance) and a script (behavior).
224 UI widgets, like our stopwatch example,
225 typically have both a template and a script.
226 But neither is required.
227 A polymer element with a script and no template is purely functional,
228 for example a [xx].
ericbidelman 2013/09/24 18:18:42 are these placeholders?
mem 2013/10/01 16:05:31 Yes they are. Was hoping for a suggestion! On 201
229 A polymer element with a template and no script is purely visual,
230 for example a [xx].
231
232 {% prettify html %}
233 <polymer-element name="tute-stopwatch">
234 <template>
235 ...
236 </template>
237 <script type="application/dart" src="tute_stopwatch.dart">
238 </script>
239 </polymer-element>
240 {% endprettify %}
241
242 <dl>
243 <dt> &lt;template&gt; </dt>
244 <dd>
245 Describes the element's structure&mdash;its user interface.
246 The template comprises any valid HTML code within the &lt;template&gt; tag.
ericbidelman 2013/09/24 18:18:42 It's important to note here that Polymer takes the
mem 2013/10/01 16:05:31 Reworded. Avoided using the term shadow root here.
247 The template is rendered when a Polymer element is instantiated.
248 The template can also include scoped CSS styles within a &lt;style&gt; tag.
ericbidelman 2013/09/24 18:18:42 FYI, the styles are scoped by default.
mem 2013/10/01 16:05:31 Done.
249 </dd>
250
251 <dt> &lt;script&gt; </dt>
252 <dd markdown="1"> Specifies a Dart script.
253 For Polymer elements, the Dart script is a Dart class
ericbidelman 2013/09/24 18:18:42 Can Polymer.dart do inline <script>?
mem 2013/10/01 16:05:31 Yes. But our tools don't give good info when editi
254 that implements the behavior of the element.
255 The class typically overrides some
256 life-cycle methods and provides event handlers
257 that join the UI with its programmatic behavior.
258 In this example, the script is in the `tute_stopwatch.dart` file.
259 </dd>
260 </dl>
261
262 ##Providing a template for the Polymer element {#providing-a-template}
263
264 Here's the template code for the tute-stopwatch element:
265
266 ![The template code for the tute-stopwatch element](images/template-code.png)
267
268 The tute-stopwatch template uses a &lt;style&gt; tag, which is optional.
269 These styles are scoped; they affect only
270 the appearance of the Polymer element and the elements it contains.
271 More about scoped CSS in [Styling a Polymer element](#scoped-css).
ericbidelman 2013/09/24 18:18:42 Suggset you also link to this article: http://www.
mem 2013/10/01 16:05:31 Done.
272
273 The rest of the code within the template tag
ericbidelman 2013/09/24 18:18:42 <template>
mem 2013/10/01 16:05:31 Done.
274 is normal HTML with two exceptions:
275
276 * {% raw %}`{{counter}}`{% endraw %}--a Polymer syntax for
ericbidelman 2013/09/24 18:18:42 "a mustache for data binding"
mem 2013/10/01 16:05:31 Included reference to mustaches, but worded it dif
277 [embedding live data on the page](#one-way-data-binding).
278
279 * `on-click`--a Polymer element attribute that lets you
ericbidelman 2013/09/24 18:18:42 "a Polymer element attribute" -> a Polymer `on-*`d
mem 2013/10/01 16:05:31 Done.
280 [declaratively attach a mouse click handler](#event-handlers)
281 to UI elements, such as buttons.
282 Polymer has other attributes for other event types, such as `on-change`.
283
284 Let's take a look at the structure of the Dart code
285 before we get into the details of data binding, event handlers,
286 and scoped CSS.
287
288 ##Providing a script for the Polymer element {#providing-a-script}
289
290 When you define a Polymer element in HTML,
291 you give it a name using the `name` attribute.
292 On the Dart side, a class implements the behavior of the Polymer element.
293 You associate the Dart class with the Polymer element using the `@CustomTag`
294 annotation and the name of the Polymer element.
295
296 ![Two parts to a Polymer element definition](images/polymer-element-definition.p ng)
297
298 This diagram gives an overview of the TuteStopwatch class:
299
300 ![The script code for the tute-stopwatch element](images/dart-script-code.png)
301
302 Any Dart class that backs a Polymer element must subclass PolymerElement.
303 For now, if you want to use data binding,
304 the class must also use ObservableMixin.
Jennifer Messerly 2013/09/24 02:36:39 this will be fixed soon! this week or next. I've a
305
306 [xx: more about PolymerElement]
307
308 [xx: more about ObservableMixin]
309
310 The class may override one of several [life-cycle methods](#life-cycle-methods)
311 such as the inserted() method you see overridden here.
312
313 The `start()` method is an event handler for the **Start** button.
314 The event handler is declaratively connected to the button.
315 Refer to [Setting up event handlers declaratively](#event-handlers) to see how.
316
317 ##Overriding life-cycle methods {#life-cycle-methods}
318
319 The stopwatch example overrides the inserted() method
320 to initialize the app.
321 The app needs a reference to each of the three buttons
322 so that it can enable and disable the buttons
323 as appropriate for the state of the app.
324 You'll notice that it gets the buttons by
325 [querying its shadow DOM](#in-the-shadows).
ericbidelman 2013/09/24 18:18:42 Do you guys have http://www.polymer-project.org/po
Jennifer Messerly 2013/09/24 18:30:06 not yet. This change is landing soon: https://code
326
327 {% prettify dart %}
328 void inserted() {
329 super.inserted();
330 startButton = getShadowRoot("tute-stopwatch").query('#startbutton');
331 stopButton = getShadowRoot("tute-stopwatch").query('#stopbutton');
332 resetButton = getShadowRoot("tute-stopwatch").query('#resetbutton');
333
334 stopButton.disabled = true;
335 resetButton.disabled = true;
336 }
337 {% endprettify %}
338
339 The inserted() method is one of four Polymer element life-cycle methods:
ericbidelman 2013/09/24 18:18:42 FYI: the lifecycle methods have been renamed. See
Jennifer Messerly 2013/09/24 18:30:06 yup. We'll have to fix this once a few of our code
340
341 * created(): called when an instance of a Polymer element is created.
342
343 * inserted(): called when an instance of a Polymer element is
344 inserted into the DOM.
345
346 * removed(): called when an instance of a Polymer element is
347 removed from the DOM.
348
349 * attributeChanged(): called when an attribute, such as `class`,
350 of an instance of the Polymer element is added, changed, or removed.
351
352 You can override any of these life-cycle methods.
353 The overriding method
354 *must* call the super class methods first.
355
356 ##Embedding live data on the page {#one-way-data-binding}
ericbidelman 2013/09/24 18:18:42 I think the title is misleading. "Using two-way da
mem 2013/10/01 16:05:31 Done.
357
358 In HTML definition of a Polymer element,
359 use double curly brackets to embed Dart data into your webpage.
360 In Dart use the `@observable` annotation in the Dart code
361 to mark the embedded data.
362 Here, the data is a string called `counter`.
363
364 ![One-way data binding](images/one-way-data-binding.png)
365
366 The stopwatch element uses a periodic Timer to fire an event every second.
Jennifer Messerly 2013/09/24 02:36:39 link to API docs for Timer?
mem 2013/10/01 16:05:31 Done.
367 When the Timer fires, it calls the `updateTImer` callback function,
sethladd 2013/09/20 23:18:36 typo
mem 2013/10/01 16:05:31 Done.
368 which modifies the `counter` string.
369 Polymer takes care of update the bound area on the HTML page.
370
371 This type of binding is called _one-way data binding_
372 because the data can change only on the Dart side.
373 Polymer also supports two-way data binding
374 in which the data can be changed on the HTML side,
375 for example with an input element,
376 and it changes the value in the Dart code.
377
378 You can use expressions within the double curly brackets.
379 <a href="http://pub.dartlang.org/packages/polymer_expressions">Polymer expressio ns</a>
380 provide the default syntax. Examples of allowable expressions include:
381
382 * {% raw %} `{{myObject.aProperty}}` {% endraw %}--property access
383 * {% raw %} `{{!empty}}` {% endraw %}--operators, like the logical not operator
384 * {% raw %} `{{myList[3]}}` {% endraw %}--list indexing
385 * {% raw %} `{{myFunction()}}` {% endraw %}--function calls
sethladd 2013/09/20 23:18:36 let's not mention function calls here. not a great
Jennifer Messerly 2013/09/24 02:36:39 mention filters? that's a good time to include fun
mem 2013/10/01 16:05:31 changed the name to make it look like a filter. Do
386
387 ##Setting up event handlers declaratively {#event-handlers}
388
389 This example has three buttons, each
390 with an event handler that is written in Dart,
391 but attached to the button declaratively from HTML.
392
393 ![Declaratively attach a click handler](images/click-handler.png)
394
395 In HTML, use the `on-click` attribute
396 to attach a mouse click handler to an HTML element.
397 The value of the attribute is the name of a method
398 in the class that implements the Polymer element.
399 When the user clicks the button the named method is called
400 with three parameters:
401
402 * the
403 <a href="https://api.dartlang.org/dart_html/Event.html" target="_blank">Event</a >
404 object contains information about the event,
405 such as its type, and when it occurred.
406
407 * detail [xx] has some vague use I'm uncertain of.
sethladd 2013/09/20 23:18:36 an object can be attached to the event. it's the "
mem 2013/10/01 16:05:31 Done.
408
409 * the <a href="https://api.dartlang.org/dart_html/Node.html" target="_blank">Nod e</a>,
410 which fired the event&mdash;the **Start** button in this case.
411
412 You can attach event handlers for other kinds of events.
413 For example, you can use `on-change` to handle events for input text elements
414 when the text changes.
415
416 ##Querying the Shadow DOM {#in-the-shadows}
sethladd 2013/09/20 23:18:36 I'd like to delay talking about or mentioning shad
mem 2013/10/01 16:05:31 I've got all the shadow dom stuff isolated here in
417
418 Hey! Remember we mentioned the shadow DOM earlier.
419 Now we get to bring it out of the shadows.
420
421 The Shadow DOM is key to encapsulation.
422 The DOM tree for a Polymer element is in the shadows,
423 hidden from outside of the Polymer element
424 (unless the Polymer element chooses to reveal them).
ericbidelman 2013/09/24 18:18:42 Not sure what you mean here. Shadow roots are disc
mem 2013/10/01 16:05:31 Done.
425
426 ![Shadow DOM for tute-stopwatch Polymer element](images/shadow-dom.png)
427
428 You can programmatically get items from the shadow DOM
ericbidelman 2013/09/24 18:18:42 Be consistent with "Shadow DOM" capitalization.
mem 2013/10/01 16:05:31 Done.
429 by querying a Polymer element's shadow root.
430
431 {% prettify dart %}
432 startButton = getShadowRoot("tute-stopwatch").query('#startbutton');
433 stopButton = getShadowRoot("tute-stopwatch").query('#stopbutton');
434 resetButton = getShadowRoot("tute-stopwatch").query('#resetbutton');
435 {% endprettify %}
436
437 Call `getShadowRoot` with the name of the Polymer element.
438 The getShadowRoot function returns the shadow root element
ericbidelman 2013/09/24 18:18:42 `getShadowRoot`
mem 2013/10/01 16:05:31 Done.
439 for 'this' instance of the element named.
ericbidelman 2013/09/24 18:18:42 `this`
mem 2013/10/01 16:05:31 Done.
440 Then use `query` with a CSS selector to get the element(s) of interest.
441
442 Note that this code uses query to get each button by id.
443 By querying the shadow root object rather than the DOM,
444 you are guaranteed to get the objects from within the Polymer element,
445 not from anywhere else on the page.
446
447 ##Styling a Polymer element {#scoped-css}
448
449 You can optionally include CSS styles for your Polymer element
450 which apply only to the contents of the Polymer element.
ericbidelman 2013/09/24 18:18:42 You can also style the element directly using `@ho
mem 2013/10/01 16:05:31 I couldn't get this to work. On 2013/09/24 18:18:
mem 2013/10/03 17:01:54 Got it done now. Adjusted the example and text. On
451
452 ![Scoped CSS styleing](images/css-styling.png)
Jennifer Messerly 2013/09/24 02:36:39 "Scoped CSS styling"?
mem 2013/10/01 16:05:31 Done.
453
454 The CSS here provide a style for the ID `stopwatch_container`,
455 which identifies the primary &lt;div&gt; element within the stopwatch template.
456 The styles within the template apply only to the template.
457 So any CSS selectors within the template need only be unique within the template .
458 You don't need to worry about naming conflicts on the page.
459
460 ##Other resources
461
462 Use these other resources to learn more about Polymer.dart:
463
464 * We converted all tutorial examples that previously used Web UI
465 to use Polymer instead.
466 Check out the
467 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web">gi thub repo</a>
468 to find the source code for all of the Polymer examples.
469
470 * Learn more about
471 <a href="http://www.dartlang.org/polymer-dart/">Polymer.dart</a>&mdash;the
472 Dart port of the Polymer project.
473
474 * Check out the Polymer project website at
475 <a href="http://www.polymer-project.org/">polymer-project.org</a>.
476
477 * The next target is going to talk about other nifty polymer.dart features like
478 two-way data binding, xtag, and the &lt;content&gt; tag and shadow DOM.
479 Aren't you excited?
480
481 Wahoo!
482
483 Go write some code.
484
485 {% endcapture %}
486
487 {% include tutorial.html %}
OLDNEW
« no previous file with comments | « src/site/docs/tutorials/polymer/images/template-code.png ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698