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

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

Issue 26922002: removing Web UI tutorials, updating remaining 4 to current release, + review pass (Closed) Base URL: https://github.com/dart-lang/dartlang.org.git@master
Patch Set: provided redirects for web UI tutes, put deprecated notice in code lab Created 7 years, 2 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
OLDNEW
1 --- 1 ---
2 layout: default 2 layout: default
3 title: "Define a Custom Element" 3 title: "Define a Custom Element"
4 description: "Create a custom HTML element using Polymer." 4 description: "Create a custom HTML element using Polymer."
5 has-permalinks: true 5 has-permalinks: true
6 tutorial: 6 tutorial:
7 id: polymer-intro 7 id: polymer-intro
8 next: fetchdata 8 next: fetchdata
9 next-title: "Fetch Data Dynamically" 9 next-title: "Fetch Data Dynamically"
10 prev: shared-pkgs 10 prev: shared-pkgs
(...skipping 29 matching lines...) Expand all
40 40
41 <div class="tute-target-title"> 41 <div class="tute-target-title">
42 <h1>{{page.title}}</h1> 42 <h1>{{page.title}}</h1>
43 <h3>Create a custom HTML element using Polymer</h3> 43 <h3>Create a custom HTML element using Polymer</h3>
44 </div> 44 </div>
45 45
46 A custom element is an HTML element you can define yourself, 46 A custom element is an HTML element you can define yourself,
47 encapsulating appearance and/or behavior 47 encapsulating appearance and/or behavior
48 within semantically meaningful HTML. 48 within semantically meaningful HTML.
49 49
50 <aside class="alert"> 50 <aside class="alert alert-info">
51 Custom elements are one feature of 51 Custom elements are one feature of
52 <a href="http://www.polymer-project.org/" 52 <a href="http://www.polymer-project.org/"
53 target="_blank">Polymer</a>, 53 target="_blank">Polymer</a>,
54 a new type of library for the web based on Web Components. 54 a new type of library for the web based on Web Components.
55 <a href="http://www.dartlang.org/polymer-dart/" 55 <a href="http://www.dartlang.org/polymer-dart/"
56 target="_blank">Polymer.dart</a> 56 target="_blank">Polymer.dart</a>
57 is the Dart implementation of Polymer. 57 is the Dart implementation of Polymer.
58 (Note: Polymer supersedes Web UI.) 58 (Note: Polymer supersedes Web UI.)
59 </aside> 59 </aside>
60 60
61 * [An example](#an-example) 61 * [An example](#an-example)
62 * [Installing Polymer.dart](#getting-polymer-dart) 62 * [Installing Polymer.dart](#getting-polymer-dart)
63 * [Including Polymer.dart in your application](#bootstrap) 63 * [Including Polymer.dart in your application](#bootstrap)
64 * [Instantiating a custom element](#instantiating) 64 * [Instantiating a custom element](#instantiating)
65 * [Defining a custom element](#define-element) 65 * [Defining a custom element](#define-element)
66 * [Providing a template for the custom element](#providing-a-template) 66 * [Providing a template for the custom element](#providing-a-template)
67 * [Providing a script for the custom element](#providing-a-script) 67 * [Providing a script for the custom element](#providing-a-script)
68 * [Overiding life-cycle methods](#life-cycle-methods) 68 * [Overiding life-cycle methods](#life-cycle-methods)
69 * [Using data binding](#data-binding) 69 * [Using data binding](#data-binding)
70 * [Setting up event handlers declaratively](#event-handlers) 70 * [Setting up event handlers declaratively](#event-handlers)
71 * [Querying the Shadow DOM](#in-the-shadows)
72 * [Styling a custom element](#scoped-css) 71 * [Styling a custom element](#scoped-css)
73 * [Other resources](#other-resources) 72 * [Other resources](#other-resources)
73 * [What next?](#what-next)
74 74
75 ##An example 75 ##An example
76 76
77 In the example running below, 77 In the example running below,
78 the LemonChiffon area outlined in black 78 the LemonChiffon area outlined in black
79 is a custom element implemented using Polymer. 79 is a custom element implemented using Polymer.
80 80
81 <strong>Try it!</strong> 81 <strong>Try it!</strong>
82 Start and stop the stopwatch. 82 Start and stop the stopwatch.
83 Reset the stopwatch to 00:00 using the **Reset** button. 83 Reset the stopwatch to 00:00 using the **Reset** button.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 The tute-stopwatch template uses a &lt;style&gt; tag, which is optional. 277 The tute-stopwatch template uses a &lt;style&gt; tag, which is optional.
278 These styles are scoped; they affect only 278 These styles are scoped; they affect only
279 the appearance of the custom element and the elements it contains. 279 the appearance of the custom element and the elements it contains.
280 More about scoped CSS in [Styling a custom element](#scoped-css). 280 More about scoped CSS in [Styling a custom element](#scoped-css).
281 281
282 The rest of the code within the &lt;template&gt; tag 282 The rest of the code within the &lt;template&gt; tag
283 is normal HTML, with two exceptions: 283 is normal HTML, with two exceptions:
284 284
285 |---|---| 285 |---|---|
286 | `{``{``counter}}` | Uses a Polymer syntax to [bind Dart data](#data-binding) t o the HTML page. The double curly braces are commonly known as a "double mustach e". | 286 | `{``{``counter}}` | Uses a Polymer syntax to [bind Dart data](#data-binding) t o the HTML page. The double curly braces are commonly known as a "double mustach e". |
287 | `on-click` | Uses Polymer [declarative event mapping](#event-handlers), which allows you to set up event handlers for a UI element. `on-click` sets up an even t handler for mouse clicks. Polymer has mappings for other event types, such as `on-change` for input change events. | 287 | `on-click` | Uses Polymer [declarative event mapping](#event-handlers), which allows you to set up event handlers for a UI element. `on-click` sets up an even t handler for mouse clicks. Polymer has mappings for other event types, such as `on-input` for changes to text fields. |
288 {: .table} 288 {: .table}
289 289
290 Let's take a look at the structure of the Dart code 290 Let's take a look at the structure of the Dart code
291 before we get into the details of data binding, event handlers, 291 before we get into the details of data binding, event handlers,
292 and scoped CSS. 292 and scoped CSS.
293 293
294 ##Providing a script for the custom element {#providing-a-script} 294 ##Providing a script for the custom element {#providing-a-script}
295 295
296 On the Dart side, a class implements the behavior of the custom element. 296 On the Dart side, a class implements the behavior of the custom element.
297 You associate the Dart class with the custom element using the `@CustomTag` 297 You associate the Dart class with the custom element using the `@CustomTag`
298 annotation and the name of the custom element. 298 annotation and the name of the custom element.
299 299
300 ![Two parts to a custom element definition](images/polymer-element-definition.pn g) 300 ![Two parts to a custom element definition](images/polymer-element-definition.pn g)
301 301
302 This diagram gives an overview of the TuteStopwatch class: 302 This diagram gives an overview of the TuteStopwatch class:
303 303
304 ![The script code for the tute-stopwatch element](images/dart-script-code.png) 304 ![The script code for the tute-stopwatch element](images/dart-script-code.png)
305 305
306 Any Dart class that backs a Polymer element must subclass PolymerElement. 306 Any Dart class that backs a Polymer element must subclass PolymerElement.
307 If you want to use data binding, the class must also use ObservableMixin.
308 307
309 {% comment %} 308 {% comment %}
310 [xx: more about PolymerElement] 309 [xx: more about PolymerElement]
311 [xx: more about ObservableMixin]
312 {% endcomment %} 310 {% endcomment %}
313 311
314 The class can respond to life-cycle milestones 312 The class can respond to life-cycle milestones
315 by overriding [life-cycle methods](#life-cycle-methods). 313 by overriding [life-cycle methods](#life-cycle-methods).
316 For example, the TuteStopwatch class overrides the `inserted()` 314 For example, the TuteStopwatch class overrides the `inserted()`
317 method&mdash;which is called when the element is inserted 315 method&mdash;which is called when the element is inserted
318 into the DOM&mdash;to initialize the app. 316 into the DOM&mdash;to initialize the app.
319 317
320 The `start()` method is an event handler for the **Start** button. 318 The `start()` method is an event handler for the **Start** button.
321 The event handler is declaratively connected to the button. 319 The event handler is declaratively connected to the button.
(...skipping 14 matching lines...) Expand all
336 You can override any of these life-cycle methods. 334 You can override any of these life-cycle methods.
337 The overriding method 335 The overriding method
338 *must* call the super class method first. 336 *must* call the super class method first.
339 337
340 The Stopwatch app overrides the `inserted()` method because it 338 The Stopwatch app overrides the `inserted()` method because it
341 needs a reference to each of the three buttons 339 needs a reference to each of the three buttons
342 so that it can enable and disable them. 340 so that it can enable and disable them.
343 When a tute-stopwatch custom element is inserted into the DOM 341 When a tute-stopwatch custom element is inserted into the DOM
344 the buttons have been created, so the references to them 342 the buttons have been created, so the references to them
345 will be available when the inserted() method is called. 343 will be available when the inserted() method is called.
346 You'll notice that it gets the buttons by
347 [querying the custom element's shadow root](#in-the-shadows).
348 344
349 {% prettify dart %} 345 {% prettify dart %}
350 void inserted() { 346 void inserted() {
351 super.inserted(); 347 super.inserted();
352 startButton = getShadowRoot('tute-stopwatch').query('#startButton'); 348 startButton = $['startButton'];
353 stopButton = getShadowRoot('tute-stopwatch').query('#stopButton'); 349 stopButton = $['stopButton'];
354 resetButton = getShadowRoot('tute-stopwatch').query('#resetButton'); 350 resetButton = $['resetButton'];
355 351
356 stopButton.disabled = true; 352 stopButton.disabled = true;
357 resetButton.disabled = true; 353 resetButton.disabled = true;
358 } 354 }
359 {% endprettify %} 355 {% endprettify %}
360 356
357 The code uses _automatic node finding_, a Polymer feature,
358 to get a reference to each button.
359 Every node in a custom element that is tagged with an `id` attribute
360 can be referenced by its ID using the syntax: `$['ID']`.
361
361 ##Using data binding {#data-binding} 362 ##Using data binding {#data-binding}
362 363
363 In the HTML definition of a custom element, 364 In the HTML definition of a custom element,
364 use double curly brackets to embed Dart data into the webpage. 365 use double curly brackets to embed Dart data into the webpage.
365 In your Dart code, use the `@observable` annotation 366 In your Dart code, use the `@observable` annotation
366 to mark the embedded data. 367 to mark the embedded data.
367 Here, the data is a string called `counter`. 368 Here, the data is a string called `counter`.
368 369
369 ![One-way data binding](images/one-way-data-binding.png) 370 ![One-way data binding](images/one-way-data-binding.png)
370 371
371 The tute-stopwatch element uses a periodic 372 The tute-stopwatch element uses a periodic
372 <a href="https://api.dartlang.org/dart_async/Timer.html" target="_blank">Timer</ a> 373 <a href="https://api.dartlang.org/dart_async/Timer.html" target="_blank">Timer</ a>
373 to fire an event every second. 374 to fire an event every second.
374 When the Timer fires, it calls the `updateTimer()` method, 375 When the Timer fires, it calls the `updateTimer()` method,
375 which modifies the `counter` string. 376 which modifies the `counter` string.
376 Polymer takes care of updating the HTML page with the new string. 377 Polymer takes care of updating the HTML page with the new string.
377 378
378 This type of binding is called _one-way data binding_ 379 This type of binding is called _one-way data binding_
379 because the data can change only on the Dart side. 380 because the data can change only on the Dart side.
380 Polymer also supports two-way data binding. 381 Polymer also supports two-way data binding.
381 In two-way data binding, when data changes on the HTML side&mdash;for example 382 In two-way data binding, when data changes on the HTML side&mdash;for example
382 with an input element&mdash;the value in the Dart code changes to match. 383 with an input element&mdash;the value in the Dart code changes to match.
384 For more information about two-way binding,
385 plus examples of using it with a variety of
386 HTML5 widgets, check out
387 [Two-way data binding using Polymer](/docs/tutorials/forms/#binding-data).
Kathy Walrath 2013/10/11 16:36:03 When I followed this link, I was a bit disoriented
mem 2013/10/11 18:21:30 Done.
383 388
384 You can use expressions within the double curly brackets. 389 You can use expressions within the double curly brackets.
385 <a href="http://pub.dartlang.org/packages/polymer_expressions" 390 <a href="http://pub.dartlang.org/packages/polymer_expressions"
386 target="_blank">Polymer expressions</a> 391 target="_blank">Polymer expressions</a>
387 provide the default syntax. Examples of allowable expressions include: 392 provide the default syntax. Examples of allowable expressions include:
388 393
389 |---|---| 394 |---|---|
390 | `{``{``myObject.aProperty}}` | Property access. | 395 | `{``{``myObject.aProperty}}` | Property access. |
391 | `{``{``!empty}}` | Operators, like the logical not operator. | 396 | `{``{``!empty}}` | Operators, like the logical not operator. |
392 | `{``{``myList[3]}}` | List indexing. | 397 | `{``{``myList[3]}}` | List indexing. |
(...skipping 19 matching lines...) Expand all
412 <a href="https://api.dartlang.org/dart_html/Event.html" target="_blank">Event</a > 417 <a href="https://api.dartlang.org/dart_html/Event.html" target="_blank">Event</a >
413 that contains information about the event, 418 that contains information about the event,
414 such as its type and when it occurred. 419 such as its type and when it occurred.
415 420
416 * The _detail_ object can provide additional, event-specific information. 421 * The _detail_ object can provide additional, event-specific information.
417 422
418 * The <a href="https://api.dartlang.org/dart_html/Node.html" target="_blank">Nod e</a> 423 * The <a href="https://api.dartlang.org/dart_html/Node.html" target="_blank">Nod e</a>
419 that fired the event&mdash;the **Start** button in this case. 424 that fired the event&mdash;the **Start** button in this case.
420 425
421 You can attach event handlers for other kinds of events. 426 You can attach event handlers for other kinds of events.
422 For example, you can use `on-change` to handle events for input text elements 427 For example, you can use `on-input` to handle events
423 when the text changes. 428 for input text elements when the text changes.
424 429
425 Refer to 430 Refer to
426 [Declarative event mapping](http://www.polymer-project.org/polymer.html#declarat ive-event-mapping) 431 [Declarative event mapping](http://www.polymer-project.org/polymer.html#declarat ive-event-mapping)
427 for further details. 432 for further details.
428 433
434 {% comment %}
429 ##Querying the shadow root {#in-the-shadows} 435 ##Querying the shadow root {#in-the-shadows}
430 436
431 The Shadow DOM is key to encapsulation. 437 The Shadow DOM is key to encapsulation.
432 The DOM subtree for a custom element is 438 The DOM subtree for a custom element is
433 hidden from outside of the custom element. 439 hidden from outside of the custom element.
434 440
435 ![Shadow DOM for tute-stopwatch custom element](images/shadow-dom.png) 441 ![Shadow DOM for tute-stopwatch custom element](images/shadow-dom.png)
436 442
437 You can programmatically get items from the Shadow DOM 443 You can programmatically get items from the Shadow DOM
438 by querying a custom element's _shadow root_&mdash;a 444 by querying a custom element's _shadow root_&mdash;a
439 special node from which an instance of a custom element is rendered. 445 special node from which an instance of a custom element is rendered.
440 446
441 {% prettify dart %} 447 {% prettify dart %}
442 startButton = getShadowRoot('tute-stopwatch').query('#startbutton'); 448 startButton = getShadowRoot('tute-stopwatch').query('#startbutton');
443 stopButton = getShadowRoot('tute-stopwatch').query('#stopbutton'); 449 stopButton = getShadowRoot('tute-stopwatch').query('#stopbutton');
444 resetButton = getShadowRoot('tute-stopwatch').query('#resetbutton'); 450 resetButton = getShadowRoot('tute-stopwatch').query('#resetbutton');
445 {% endprettify %} 451 {% endprettify %}
446 452
447 Call `getShadowRoot()` with the name of the custom element. 453 Call `getShadowRoot()` with the name of the custom element.
448 The `getShadowRoot()` method returns the shadow root element 454 The `getShadowRoot()` method returns the shadow root element
449 for this instance of the specified element. 455 for this instance of the specified element.
450 Use `query()` with a CSS selector to get the element(s) of interest. 456 Use `query()` with a CSS selector to get the element(s) of interest.
451 457
452 Note that this code uses `query()` to get each button by ID. 458 Note that this code uses `query()` to get each button by ID.
453 By querying the shadow root object rather than the DOM, 459 By querying the shadow root object rather than the DOM,
454 you are guaranteed to get the objects from within the custom element, 460 you are guaranteed to get the objects from within the custom element,
455 not from anywhere else on the page. 461 not from anywhere else on the page.
462 {% endcomment %}
456 463
457 ##Styling a custom element {#scoped-css} 464 ##Styling a custom element {#scoped-css}
458 465
459 You can optionally include CSS styles for your custom element 466 You can optionally include CSS styles for your custom element
460 that apply only to the contents of the custom element. 467 that apply only to the contents of the custom element.
461 468
462 ![Scoped CSS styling](images/css-styling.png) 469 ![Scoped CSS styling](images/css-styling.png)
463 470
464 The `@host` rule allows you to target and style an element internally, 471 The `@host` rule allows you to target and style an element internally,
465 from within its definition. 472 from within its definition.
466 The `:scope` pseudo-class refers to the custom element itself. 473 The `:scope` pseudo-class refers to the custom element itself.
467 The only selectors that work in `@host` are those targeting the host element its elf. 474 The only selectors that work within `@host` are those contained
475 in the host element itself.
468 So you don't need to worry about naming conflicts on the page. 476 So you don't need to worry about naming conflicts on the page.
469 Any CSS selectors within the template need to be unique only within the template . 477 Any CSS selectors within the template need to be unique only within the template .
470 478
471 For further details about styling custom elements, 479 For further details about styling custom elements,
472 refer to 480 refer to
473 [A Guide to Styling Elements](http://www.polymer-project.org/articles/styling-el ements.html) 481 [A Guide to Styling Elements](http://www.polymer-project.org/articles/styling-el ements.html)
474 482
475 ##Other resources 483 ##Other resources
476 484
477 Use these other resources to learn more about Polymer: 485 Use these other resources to learn more about Polymer:
478 486
479 * The tutorial 487 * The tutorial
480 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web" 488 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web"
481 target="_blank">github repo</a> 489 target="_blank">github repo</a>
482 contains many examples that use Polymer, 490 contains many examples that use Polymer,
483 including samples that have been converted from Web UI. 491 including samples that have been converted from Web UI.
484 492
485 * The 493 * The
486 <a href="http://www.dartlang.org/polymer-dart/" 494 <a href="http://www.dartlang.org/polymer-dart/"
487 target="_blank">Polymer.dart</a> homepage provides information 495 target="_blank">Polymer.dart</a> homepage provides information
488 specific to the Dart port of the Polymer project. 496 specific to the Dart port of the Polymer project.
489 497
490 * The Polymer project website 498 * The Polymer project website
491 <a href="http://www.polymer-project.org/" 499 <a href="http://www.polymer-project.org/"
492 target="_blank">polymer-project.org</a> 500 target="_blank">polymer-project.org</a>
493 contains information about the Polymer project as a whole. 501 contains information about the Polymer project as a whole.
494 502
503 ##What next?
504
505 [Two-way data binding with Polymer](/docs/tutorials/forms/#binding-data)
506 in the tutorial about forms shows how to use two-way data binding
Kathy Walrath 2013/10/11 16:36:03 ah, I see you gave the context here. (just do the
mem 2013/10/11 18:21:30 Done.
507 with various types of input elements such as text fields, color pickers,
508 and so on.
509
510 Check out these other tutorial examples that use Polymer.
Kathy Walrath 2013/10/11 16:36:03 . -> :
mem 2013/10/11 18:21:30 Done.
511
512 * <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/f etchdata/its_all_about_you"
513 target="_blank">its_all_about_you</a>
514 * <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/f orms/slambook"
515 target="_blank">slambook</a>
516 * <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/i ndexeddb/count_down"
517 target="_blank">count_down</a>
518
519 The next tutorial,
520 [Fetch Data Dynamically](/docs/tutorials/fetchdata/),
521 shows you how to fetch data
522 and use JSON to encode and decode
523 that data.
524
495 {% endcapture %} 525 {% endcapture %}
496 526
497 {% include tutorial.html %} 527 {% include tutorial.html %}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698