| OLD | NEW |
| 1 --- | 1 --- |
| 2 layout: tutorial | 2 layout: tutorial |
| 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: futures/ | 8 next: futures/ |
| 9 next-title: "Use Future-Based APIs" | 9 next-title: "Use Future-Based APIs" |
| 10 prev: shared-pkgs/ | 10 prev: shared-pkgs/ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 <h3>Create a custom HTML element using Polymer</h3> | 42 <h3>Create a custom HTML element using Polymer</h3> |
| 43 </div> | 43 </div> |
| 44 | 44 |
| 45 A custom element is an HTML element you can define yourself, | 45 A custom element is an HTML element you can define yourself, |
| 46 encapsulating appearance and/or behavior | 46 encapsulating appearance and/or behavior |
| 47 within semantically meaningful HTML. | 47 within semantically meaningful HTML. |
| 48 | 48 |
| 49 <aside class="alert"> | 49 <aside class="alert"> |
| 50 <strong>Version Note:</strong> The code sample and the content | 50 <strong>Version Note:</strong> The code sample and the content |
| 51 of this tutorial are compatible with | 51 of this tutorial are compatible with |
| 52 <a href="https://pub.dartlang.org/packages/polymer#versions">polymer.dart 0.9</a
>. | 52 <a href="https://pub.dartlang.org/packages/polymer#versions">polymer.dart 0.10.<
/a>. |
| 53 </aside> | 53 </aside> |
| 54 | 54 |
| 55 <aside class="alert alert-info"> | 55 <aside class="alert alert-info"> |
| 56 Custom elements are one feature of | 56 Custom elements are one feature of |
| 57 <a href="http://www.polymer-project.org/" | 57 <a href="http://www.polymer-project.org/" |
| 58 target="_blank">Polymer</a>, | 58 target="_blank">Polymer</a>, |
| 59 a new type of library for the web based on Web Components. | 59 a new type of library for the web based on Web Components. |
| 60 <a href="http://www.dartlang.org/polymer-dart/" | 60 <a href="http://www.dartlang.org/polymer-dart/" |
| 61 target="_blank">Polymer.dart</a> | 61 target="_blank">Polymer.dart</a> |
| 62 is the Dart implementation of Polymer. | 62 is the Dart implementation of Polymer. |
| 63 (Note: Polymer supersedes Web UI.) | |
| 64 </aside> | 63 </aside> |
| 65 | 64 |
| 66 * [An example](#an-example) | 65 * [An example](#an-example) |
| 67 * [Installing Polymer.dart](#getting-polymer-dart) | 66 * [Installing Polymer.dart](#getting-polymer-dart) |
| 68 * [Including Polymer.dart in your application](#bootstrap) | 67 * [Including Polymer.dart in your application](#bootstrap) |
| 69 * [Instantiating a custom element](#instantiating) | 68 * [Instantiating a custom element](#instantiating) |
| 70 * [Defining a custom element](#define-element) | 69 * [Defining a custom element](#define-element) |
| 71 * [Providing a template for the custom element](#providing-a-template) | 70 * [Providing a template for the custom element](#providing-a-template) |
| 72 * [Providing a script for the custom element](#providing-a-script) | 71 * [Providing a script for the custom element](#providing-a-script) |
| 73 * [Overiding life-cycle methods](#life-cycle-methods) | 72 * [Overiding life-cycle methods](#life-cycle-methods) |
| 74 * [Using data binding](#data-binding) | 73 * [Using data binding](#data-binding) |
| 75 * [Setting up event handlers declaratively](#event-handlers) | 74 * [Setting up event handlers declaratively](#event-handlers) |
| 76 * [Styling a custom element](#scoped-css) | 75 * [Styling a custom element](#scoped-css) |
| 76 * [Deploying an app that uses Polymer](#deploying-an-app-that-uses-polymer) |
| 77 * [Other resources](#other-resources) | 77 * [Other resources](#other-resources) |
| 78 * [What next?](#what-next) | 78 * [What next?](#what-next) |
| 79 | 79 |
| 80 ##An example | 80 ##An example |
| 81 | 81 |
| 82 In the example running below, | 82 In the example running below, |
| 83 the LemonChiffon area outlined in black | 83 the LemonChiffon area outlined in black |
| 84 is a custom element implemented using Polymer. | 84 is a custom element implemented using Polymer. |
| 85 | 85 |
| 86 <strong>Try it!</strong> | 86 <strong>Try it!</strong> |
| 87 Start and stop the stopwatch. | 87 Start and stop the stopwatch. |
| 88 Reset the stopwatch to 00:00 using the **Reset** button. | 88 Reset the stopwatch to 00:00 using the **Reset** button. |
| 89 | 89 |
| 90 <iframe class="running-app-frame" | 90 <iframe class="running-app-frame" |
| 91 style="height:220px;width:230px;" | 91 style="height:220px;width:230px;" |
| 92 src="examples/stopwatch/out/web/index.html"> | 92 src="examples/stopwatch/web/index.html"> |
| 93 </iframe> | 93 </iframe> |
| 94 | 94 |
| 95 To place this custom element on an HTML page, | 95 Here's how to use this custom element in an HTML page: |
| 96 import the file with the custom element definition | 96 |
| 97 and use the name of the element as an HTML tag: | 97 * Import `packages/polymer/polymer.html`. |
| 98 * Import the HTML file that has the custom element definition |
| 99 (`tute_stopwatch.html`). |
| 100 * Use the name of the element as an HTML tag |
| 101 (`<tute-stopwatch>`). |
| 102 * Initialize Polymer, which you can do using Polymer's |
| 103 `init.dart` file. |
| 104 |
| 105 For example: |
| 98 | 106 |
| 99 {% prettify html %} | 107 {% prettify html %} |
| 108 <link rel="import" href="packages/polymer/polymer.html"> |
| 100 <link rel="import" href="tute_stopwatch.html"> | 109 <link rel="import" href="tute_stopwatch.html"> |
| 101 ... | 110 ... |
| 102 <tute-stopwatch></tute-stopwatch> | 111 <tute-stopwatch></tute-stopwatch> |
| 112 |
| 113 <script type="application/dart">export 'package:polymer/init.dart';</script> |
| 103 {% endprettify %} | 114 {% endprettify %} |
| 104 | 115 |
| 105 The counting text, the three buttons along with their actions, | 116 The counting text, the three buttons along with their actions, |
| 106 and the style are all contained within the custom element. | 117 and the style are all contained within the custom element. |
| 107 The definition of the custom element encapsulates and | 118 The definition of the custom element encapsulates and |
| 108 hides the implementation details, | 119 hides the implementation details, |
| 109 which as the user of the element, you care nothing about. | 120 which as the user of the element, you care nothing about. |
| 110 | 121 |
| 111 When you use developer tools to inspect the element, | |
| 112 you see just the custom element's begin and end tags. | |
| 113 | |
| 114 <img class="scale-img-max" src="images/dev-tools-dom.png" | |
| 115 alt="Custom element encapsulates its contents"> | |
| 116 | |
| 117 With custom elements, you can easily create new kinds of elements | 122 With custom elements, you can easily create new kinds of elements |
| 118 that have semantically meaningful tags and that are easy to share, | 123 that have semantically meaningful tags and that are easy to share, |
| 119 reuse, and read. | 124 reuse, and read. |
| 120 | 125 |
| 121 ###Overview of the example files | 126 ###Overview of the example files |
| 122 | 127 |
| 123 Three main source files implement the Stopwatch example: | 128 Three main source files implement the Stopwatch example: |
| 124 | 129 |
| 125 <dl> | 130 <dl> |
| 126 <dt> | 131 <dt> |
| 127 index.html | 132 index.html |
| 128 </dt> | 133 </dt> |
| 129 <dd> | 134 <dd> |
| 130 The primary HTML file for the app. | 135 The primary HTML file for the app. |
| 131 Includes the Polymer bootstrap script and instantiates the custom element. | 136 It imports HTML files for Polymer and the custom element, |
| 137 and it instantiates the custom element. |
| 132 </dd> | 138 </dd> |
| 133 <dt> | 139 <dt> |
| 134 tute_stopwatch.html | 140 tute_stopwatch.html |
| 135 </dt> | 141 </dt> |
| 136 <dd> | 142 <dd> |
| 137 The HTML code that defines the custom element. | 143 The HTML code that defines the custom element. |
| 138 </dd> | 144 </dd> |
| 139 <dt> | 145 <dt> |
| 140 tute_stopwatch.dart | 146 tute_stopwatch.dart |
| 141 </dt> | 147 </dt> |
| 142 <dd> | 148 <dd> |
| 143 The Dart class that implements the custom element. | 149 The Dart class that implements the custom element. |
| 144 </dd> | 150 </dd> |
| 145 </dl> | 151 </dl> |
| 146 | 152 |
| 147 The following diagram shows the structure of the example | 153 The following diagram shows the structure of the example |
| 148 app and its use of custom elements. | 154 app and its use of custom elements: |
| 155 |
| 156 * <span style="background: rgb(249, 238, 172);"> |
| 157 Import Polymer</span> |
| 158 * <span style="background: rgb(190, 249, 221);"> |
| 159 Import custom element definition</span> |
| 160 * <span style="background: rgb(209, 226, 254);"> |
| 161 Define, implement, and instantiate custom element by name</span> |
| 162 * <span style="background: rgb(235,220,201);"> |
| 163 Initialize Polymer</span> |
| 164 * <span style="background: rgb(242, 209, 235);"> |
| 165 Associate Dart class with custom element definition</span> |
| 149 | 166 |
| 150 <img class="scale-img-max" src="images/connections.png" | 167 <img class="scale-img-max" src="images/connections.png" |
| 151 alt="The connections between Dart and HTML"> | 168 alt="The connections between Dart and HTML"> |
| 152 | 169 |
| 170 |
| 153 ##Installing Polymer.dart {#getting-polymer-dart} | 171 ##Installing Polymer.dart {#getting-polymer-dart} |
| 154 | 172 |
| 155 To use the features provided by Polymer.dart, | 173 To use the features provided by Polymer.dart, |
| 156 you need to install the Polymer package. | 174 you need to install the Polymer package. |
| 157 If you are unfamiliar with installing packages, | 175 If you are unfamiliar with installing packages, |
| 158 refer to | 176 refer to |
| 159 <a href="/docs/tutorials/shared-pkgs/">Install Shared Packages</a>, | 177 <a href="/docs/tutorials/shared-pkgs/">Install Shared Packages</a>, |
| 160 which describes the process in detail. | 178 which describes the process in detail. |
| 161 | 179 |
| 162 In brief, to install the Polymer package: | 180 In brief, to install the Polymer package: |
| 163 | 181 |
| 164 * In the application's `pubspec.yaml` file, | 182 <ul markdown="1"> |
| 183 <li markdown="1"> |
| 184 In the application's `pubspec.yaml` file, |
| 165 add the package to the list of dependencies | 185 add the package to the list of dependencies |
| 166 by adding the package name, `polymer`, to the list. | 186 by adding the package name, `polymer`, to the list. |
| 187 |
| 188 <pre> |
| 189 name: stopwatch |
| 190 description: A sample application |
| 191 dependencies: |
| 192 <b>polymer: ">=0.10.0 <0.11.0"</b> |
| 193 </pre> |
| 194 </li> |
| 195 |
| 196 <aside class="alert alert-warning"> |
| 197 <b>Important:</b> |
| 167 YAML is whitespace-sensitive, | 198 YAML is whitespace-sensitive, |
| 168 so take care to indent the package name as shown: | 199 so take care to indent the package name as shown. |
| 200 </aside> |
| 169 | 201 |
| 170 <img class="scale-img-max" src="images/sample-pubspec.png" | 202 <li markdown="1"> |
| 171 alt="Sample pubspec file with polymer dependency"> | 203 Run `pub get`, |
| 172 | |
| 173 * Run `pub get`, | |
| 174 which recursively installs the polymer.dart package | 204 which recursively installs the polymer.dart package |
| 175 and all the packages that it depends on. | 205 and all the packages that it depends on. |
| 176 If you are using Dart Editor, | 206 If you are using Dart Editor, |
| 177 when you save pubspec.yaml | 207 when you save pubspec.yaml |
| 178 the editor automatically runs `pub get` for you. | 208 the editor automatically runs `pub get` for you. |
| 179 If you are using command line tools, | 209 If you are using command-line tools, |
| 180 you can run it with the command `pub get`. | 210 you can use the command `pub get`. |
| 211 </li> |
| 212 </ul> |
| 181 | 213 |
| 182 ##Including Polymer.dart in your application {#bootstrap} | 214 ##Including Polymer.dart in your application {#bootstrap} |
| 183 | 215 |
| 184 To use Polymer.dart features such as custom elements, | 216 To use Polymer.dart features such as custom elements, |
| 185 you need to include Polymer in both | 217 you need to include Polymer in both |
| 186 the HTML side and the Dart side of your app. | 218 the HTML side and the Dart side of your app. |
| 187 | 219 |
| 188 * In the primary HTML file for your app, | 220 <aside class="alert alert-warning"> |
| 189 export `package:polymer/init.dart` within a <script> tag | 221 <b>Important:</b> |
| 190 in the <head> section. | 222 Unlike other Dart web apps, |
| 191 This script contains the `main()` function | 223 Polymer apps have no <tty>main()</tty> function |
| 192 for the app and initializes Polymer. | 224 and do not use <tty>packages/browser/dart.js</tty>. |
| 193 | 225 </aside> |
| 194 <img class="scale-img-max" src="images/init-script.png" | |
| 195 alt="Include the Polymer init script"> | |
| 196 | 226 |
| 197 * In the primary HTML file for your app, | 227 * In the primary HTML file for your app, |
| 198 include the `packages/browser/dart.js` bootstrap script | 228 import `packages/polymer/polymer.html` |
| 199 in the <head> section. | 229 in the the <head> section: |
| 200 | 230 |
| 201 <img class="scale-img-max" src="images/bootstrap-script.png" | 231 <pre> |
| 202 alt="Include the Polymer bootstrap script"> | 232 <head> |
| 233 ... |
| 234 <b><link rel="import" href="packages/polymer/polymer.html"></b> |
| 235 ... |
| 236 </head> |
| 237 </pre> |
| 203 | 238 |
| 204 * In your Dart code, import the Polymer library: | 239 * In your Dart code, import the Polymer library: |
| 205 | 240 |
| 206 <img class="scale-img-max" src="images/polymer-library.png" | 241 <pre> |
| 207 alt="Import the Polymer library"> | 242 import 'dart:html'; |
| 243 import 'dart:async'; |
| 244 <b>import 'package:polymer/polymer.dart';</b> |
| 245 ... |
| 246 </pre> |
| 208 | 247 |
| 209 ##Instantiating a custom element {#instantiating} | 248 ##Instantiating a custom element {#instantiating} |
| 210 | 249 |
| 211 To create an instance of a custom element, | 250 For most custom elements, you create an instance |
| 212 use the name of the custom element just as you would any normal HTML tag. | 251 using the name of the custom element, |
| 252 just as you would any normal HTML tag. |
| 213 In this example, the tag name is `tute-stopwatch`. | 253 In this example, the tag name is `tute-stopwatch`. |
| 214 | 254 |
| 215 <img class="scale-img-max" src="images/polymer-instance-create.png" | 255 <img class="scale-img-max" src="images/polymer-instance-create.png" |
| 216 alt="Instantiate a custom element with a custom tag"> | 256 alt="Instantiate a custom element with a custom tag"> |
| 217 | 257 |
| 218 Using best practices, | 258 Using best practices, |
| 219 the custom element definition is in a separate file. | 259 the custom element definition is in a separate file. |
| 220 Use `link [rel="import"]` to import the HTML definition file as shown. | 260 Use `link [rel="import"]` to import the HTML definition file as shown. |
| 221 | 261 |
| 262 Instantiating a <em>type extension custom element</em>—a |
| 263 custom element that inherits from a native element—is slightly different. |
| 264 For this kind of custom element, |
| 265 you use the native element name—for example, `li`—and |
| 266 then add an `is` attribute that specifies the custom element name. |
| 267 For example, here's how you instantiate a my-li element |
| 268 that extends the <li> element: |
| 269 |
| 270 <!-- Code is from polymer_list/web/index.html --> |
| 271 <pre> |
| 272 <b><li is="my-li"></b> Item #2 (custom list item) <b></li></b> |
| 273 </pre> |
| 274 |
| 222 ##Defining a custom element {#define-element} | 275 ##Defining a custom element {#define-element} |
| 223 | 276 |
| 224 The definition for the <tute-stopwatch> element is | 277 The definition for the <tute-stopwatch> element is |
| 225 in tute_stopwatch.html. | 278 in tute_stopwatch.html. |
| 226 A custom element definition should be in its own | 279 A custom element definition should be in its own |
| 227 source file so that it can be included by other files. | 280 source file so that it can be included by other files. |
| 228 An HTML file that contains the definition for a custom element | 281 An HTML file that contains the definition for a custom element |
| 229 does not need <html>, <head>, or <body> tags. | 282 does not need <html>, <head>, or <body> tags. |
| 230 | 283 |
| 231 To define a custom element, | 284 To define a custom element, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 249 typically have both a template and a script, | 302 typically have both a template and a script, |
| 250 but neither is required. | 303 but neither is required. |
| 251 A custom element with a script and no template is purely functional. | 304 A custom element with a script and no template is purely functional. |
| 252 A custom element with a template and no script is purely visual. | 305 A custom element with a template and no script is purely visual. |
| 253 | 306 |
| 254 {% prettify html %} | 307 {% prettify html %} |
| 255 <polymer-element name="tute-stopwatch"> | 308 <polymer-element name="tute-stopwatch"> |
| 256 <template> | 309 <template> |
| 257 ... | 310 ... |
| 258 </template> | 311 </template> |
| 259 <script type="application/dart" src="tute_stopwatch.dart"> | 312 <script type="application/dart" src="tute_stopwatch.dart"></script> |
| 260 </script> | |
| 261 </polymer-element> | 313 </polymer-element> |
| 262 {% endprettify %} | 314 {% endprettify %} |
| 263 | 315 |
| 264 <dl> | 316 <dl> |
| 265 <dt> <template> </dt> | 317 <dt> <template> </dt> |
| 266 <dd> | 318 <dd> |
| 267 Describes the custom element's structure—its user interface. | 319 Describes the custom element's structure—its user interface. |
| 268 The template comprises any valid HTML code within the <template> tag. | 320 The template comprises any valid HTML code within the <template> tag. |
| 269 When the custom element is instantiated, | 321 When the custom element is instantiated, |
| 270 the instance is created from the template. | 322 the instance is created from the template. |
| 271 The template can include CSS styles within a <style> tag. | 323 The template can include CSS styles within a <style> tag. |
| 272 </dd> | 324 </dd> |
| 273 | 325 |
| 274 <dt> <script> </dt> | 326 <dt> <script> </dt> |
| 275 <dd markdown="1"> Specifies a Dart script. | 327 <dd markdown="1"> Specifies a Dart script. |
| 276 For custom elements, the Dart script is a Dart class | 328 For custom elements, the Dart script is a Dart class |
| 277 that implements the behavior of the element. | 329 that implements the behavior of the element. |
| 278 The class typically overrides some | 330 The class typically overrides some |
| 279 life-cycle methods and provides event handlers | 331 life-cycle methods and provides event handlers |
| 280 that join the UI with its programmatic behavior. | 332 that join the UI with its programmatic behavior. |
| 281 In this example, the script is in tute_stopwatch.dart. | 333 In this example, the script is in tute_stopwatch.dart. |
| 334 The script type for custom elements must be |
| 335 "application/dart". |
| 282 </dd> | 336 </dd> |
| 283 </dl> | 337 </dl> |
| 284 | 338 |
| 285 ##Providing a template for the custom element {#providing-a-template} | 339 ##Providing a template for the custom element {#providing-a-template} |
| 286 | 340 |
| 287 Here's the template code for the tute-stopwatch element: | 341 Here's the template code for the tute-stopwatch element: |
| 288 | 342 |
| 289 <img class="scale-img-max" src="images/template-code.png" | 343 <img class="scale-img-max" src="images/template-code.png" |
| 290 alt="The template code for the tute-stopwatch element"> | 344 alt="The template code for the tute-stopwatch element"> |
| 291 | 345 |
| 292 The tute-stopwatch template uses a <style> tag, which is optional. | 346 The tute-stopwatch template uses a <style> tag, which is optional. |
| 293 These styles are scoped; they affect only | 347 These styles are scoped; they affect only |
| 294 the appearance of the custom element and the elements it contains. | 348 the appearance of the custom element and the elements it contains. |
| 295 More about scoped CSS in [Styling a custom element](#scoped-css). | 349 More about scoped CSS in [Styling a custom element](#scoped-css). |
| 296 | 350 |
| 297 The rest of the code within the <template> tag | 351 The rest of the code within the <template> tag |
| 298 is normal HTML, with two exceptions: | 352 is normal HTML, with two exceptions: |
| 299 | 353 |
| 300 |---|---| | 354 |---|---| |
| 301 | `{``{``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". | | 355 | `{``{`<em><code>expression</code></em>`}}` | Uses a Polymer syntax to [bind Da
rt data](#data-binding) to the HTML page. The double curly braces are commonly k
nown as a "double mustache". | |
| 302 | `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. | | 356 | `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. | |
| 303 {: .table} | 357 {: .table} |
| 304 | 358 |
| 305 Let's take a look at the structure of the Dart code | 359 Let's take a look at the structure of the Dart code |
| 306 before we get into the details of data binding, event handlers, | 360 before we get into the details of data binding, event handlers, |
| 307 and scoped CSS. | 361 and scoped CSS. |
| 308 | 362 |
| 309 ##Providing a script for the custom element {#providing-a-script} | 363 ##Providing a script for the custom element {#providing-a-script} |
| 310 | 364 |
| 311 On the Dart side, a class implements the behavior of the custom element. | 365 On the Dart side, a class implements the behavior of the custom element. |
| 312 You associate the Dart class with the custom element using the `@CustomTag` | 366 You associate the Dart class with the custom element using the `@CustomTag` |
| 313 annotation and the name of the custom element. | 367 annotation and the name of the custom element. |
| 314 | 368 |
| 315 <img class="scale-img-max" src="images/polymer-element-definition.png" | 369 <img class="scale-img-max" src="images/polymer-element-definition.png" |
| 316 alt="Two parts to a custom element definition"> | 370 alt="Two parts to a custom element definition"> |
| 317 | 371 |
| 318 This diagram gives an overview of the TuteStopwatch class: | 372 This diagram gives an overview of the TuteStopwatch class: |
| 319 | 373 |
| 320 <img class="scale-img-max" src="images/dart-script-code.png" | 374 <img class="scale-img-max" src="images/dart-script-code.png" |
| 321 alt="The script code for the tute-stopwatch element"> | 375 alt="The script code for the tute-stopwatch element"> |
| 322 | 376 |
| 323 Any Dart class that backs a Polymer element must subclass PolymerElement. | 377 Classes that back Polymer elements are usually subclasses of PolymerElement, |
| 378 but they don't have to be. |
| 379 They can extend any other HtmlElement subclass, |
| 380 but they must follow a couple of rules: |
| 381 |
| 382 * Implement |
| 383 <a href="https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/polym
er/polymer.Polymer">Polymer</a> and |
| 384 <a href="https://api.dartlang.org/observe/observe.Observable">Observable</a>. |
| 385 The easiest approach is to use Polymer and Observable as mixins. |
| 386 * Provide a constructor named |
| 387 <code><em>CustomElement</em>.created()</code> |
| 388 that invokes `super.created()` and |
| 389 (if using Polymer as a mixin) `polymerCreated()`. |
| 390 |
| 391 As an example, here's the code for a custom subclass of |
| 392 [LIElement](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart
-dom-html.LIElement): |
| 393 |
| 394 {% prettify dart %} |
| 395 @CustomTag('my-li') |
| 396 class MyListElement extends LIElement with Polymer, Observable { |
| 397 MyListElement.created() : super.created() { |
| 398 polymerCreated(); |
| 399 } |
| 400 } |
| 401 {% endprettify %} |
| 324 | 402 |
| 325 {% comment %} | 403 {% comment %} |
| 326 [xx: more about PolymerElement] | 404 [xx: more about PolymerElement] |
| 327 {% endcomment %} | 405 {% endcomment %} |
| 328 | 406 |
| 329 The class can respond to life-cycle milestones | 407 ##Overriding life-cycle methods {#life-cycle-methods} |
| 408 |
| 409 Your custom element's backing class can respond to life-cycle milestones |
| 330 by overriding [life-cycle methods](#life-cycle-methods). | 410 by overriding [life-cycle methods](#life-cycle-methods). |
| 331 For example, the TuteStopwatch class overrides the `enteredView()` | 411 For example, the TuteStopwatch class overrides the `attached()` |
| 332 method—which is called when the element is inserted | 412 method—which is called when the element is inserted |
| 333 into the DOM—to initialize the app. | 413 into the DOM—to initialize the app. |
| 334 | 414 |
| 335 The `start()` method is an event handler for the **Start** button. | 415 The `start()` method is an event handler for the **Start** button. |
| 336 The event handler is declaratively connected to the button. | 416 The event handler is declaratively connected to the button. |
| 337 Refer to [Setting up event handlers declaratively](#event-handlers) to see how. | 417 Refer to [Setting up event handlers declaratively](#event-handlers) to see how. |
| 338 | 418 |
| 339 ##Overriding life-cycle methods {#life-cycle-methods} | |
| 340 | 419 |
| 341 A custom element has four life-cycle methods | 420 A custom element has a constructor and three life-cycle methods |
| 342 that it can override: | 421 that it can override: |
| 343 | 422 |
| 344 |---|---| | 423 |---|---| |
| 345 | `created()` | Called when an instance of a custom element is created. | | 424 | <code><em>CustomElement</em>.created()</code> | The constructor used when crea
ting an instance of a custom element. | |
| 346 | `enteredView()` | Called when an instance of a custom element is inserted into
the DOM. | | 425 | `attached()` | Called when an instance of a custom element is inserted into th
e DOM. (Previously named `enteredView`.) | |
| 347 | `leftView()` | Called when an instance of a custom element is removed from the
DOM. | | 426 | `detached()` | Called when an instance of a custom element is removed from the
DOM. (Previously named `leftView`.) | |
| 348 | `attributeChanged()` | Called when an attribute, such as `class`, of an instan
ce of the custom element is added, changed, or removed. | | 427 | `attributeChanged()` | Called when an attribute, such as `class`, of an instan
ce of the custom element is added, changed, or removed. | |
| 349 {: .table} | 428 {: .table} |
| 350 | 429 |
| 351 You can override any of these life-cycle methods. | 430 You can implement the constructor, |
| 352 The overriding method | 431 if necessary, |
| 353 *must* call the super class method first. | 432 and override any of the life-cycle methods. |
| 433 The constructor or overriding method |
| 434 *must* call the superclass constructor or method first. |
| 354 | 435 |
| 355 The Stopwatch app overrides the `enteredView()` method because it | 436 The Stopwatch app overrides the `attached()` method because it |
| 356 needs a reference to each of the three buttons | 437 needs a reference to each of the three buttons |
| 357 so that it can enable and disable them. | 438 so that it can enable and disable them. |
| 358 When a tute-stopwatch custom element is inserted into the DOM | 439 When a tute-stopwatch custom element is inserted into the DOM |
| 359 the buttons have been created, so the references to them | 440 the buttons have been created, so the references to them |
| 360 will be available when the enteredView() method is called. | 441 will be available when the attached() method is called. |
| 361 | 442 |
| 362 {% prettify dart %} | 443 {% prettify dart %} |
| 363 void enteredView() { | 444 void attached() { |
| 364 super.enteredView(); | 445 super.attached(); |
| 365 startButton = $['startButton']; | 446 startButton = $['startButton']; |
| 366 stopButton = $['stopButton']; | 447 stopButton = $['stopButton']; |
| 367 resetButton = $['resetButton']; | 448 resetButton = $['resetButton']; |
| 368 | 449 |
| 369 stopButton.disabled = true; | 450 stopButton.disabled = true; |
| 370 resetButton.disabled = true; | 451 resetButton.disabled = true; |
| 371 } | 452 } |
| 372 {% endprettify %} | 453 {% endprettify %} |
| 373 | 454 |
| 374 The code uses _automatic node finding_, a Polymer feature, | 455 The code uses _automatic node finding_, a Polymer feature, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 | 487 |
| 407 You can use expressions within the double curly brackets. | 488 You can use expressions within the double curly brackets. |
| 408 <a href="http://pub.dartlang.org/packages/polymer_expressions" | 489 <a href="http://pub.dartlang.org/packages/polymer_expressions" |
| 409 target="_blank">Polymer expressions</a> | 490 target="_blank">Polymer expressions</a> |
| 410 provide the default syntax. Examples of allowable expressions include: | 491 provide the default syntax. Examples of allowable expressions include: |
| 411 | 492 |
| 412 |---|---| | 493 |---|---| |
| 413 | `{``{``myObject.aProperty}}` | Property access. | | 494 | `{``{``myObject.aProperty}}` | Property access. | |
| 414 | `{``{``!empty}}` | Operators, like the logical not operator. | | 495 | `{``{``!empty}}` | Operators, like the logical not operator. | |
| 415 | `{``{``myList[3]}}` | List indexing. | | 496 | `{``{``myList[3]}}` | List indexing. | |
| 497 {: .table} |
| 498 |
| 499 {% comment %} |
| 500 Add back the filter row when the syntax has settled down. |
| 416 | `{``{``myFilter()}}` | Data filtering. | | 501 | `{``{``myFilter()}}` | Data filtering. | |
| 417 {: .table} | 502 |
| 503 Here's a relevant discussion: |
| 504 https://groups.google.com/a/dartlang.org/forum/#!msg/web/W23NZoLjb7U/1331Id4vl7E
J |
| 505 {% endcomment %} |
| 418 | 506 |
| 419 ##Setting up event handlers declaratively {#event-handlers} | 507 ##Setting up event handlers declaratively {#event-handlers} |
| 420 | 508 |
| 421 This example has three buttons, each | 509 This example has three buttons, each |
| 422 with an event handler that is written in Dart, | 510 with an event handler that is written in Dart, |
| 423 but attached to the button declaratively from HTML. | 511 but attached to the button declaratively from HTML. |
| 424 | 512 |
| 425 <img class="scale-img-max" src="images/click-handler.png" | 513 <img class="scale-img-max" src="images/click-handler.png" |
| 426 alt="Declaratively attach a click handler"> | 514 alt="Declaratively attach a click handler"> |
| 427 | 515 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 You can style elements within the custom element using | 582 You can style elements within the custom element using |
| 495 the appropriate selectors for those elements. | 583 the appropriate selectors for those elements. |
| 496 You don't need to worry about naming conflicts on the page. | 584 You don't need to worry about naming conflicts on the page. |
| 497 Any CSS selectors used within the <style> section | 585 Any CSS selectors used within the <style> section |
| 498 apply only to those elements within the template. | 586 apply only to those elements within the template. |
| 499 | 587 |
| 500 For further details about styling custom elements, | 588 For further details about styling custom elements, |
| 501 refer to | 589 refer to |
| 502 [A Guide to Styling Elements](http://www.polymer-project.org/articles/styling-el
ements.html) | 590 [A Guide to Styling Elements](http://www.polymer-project.org/articles/styling-el
ements.html) |
| 503 | 591 |
| 592 |
| 593 ##Deploying an app that uses Polymer |
| 594 |
| 595 To convert your app to JavaScript |
| 596 that you can deploy to the web, |
| 597 you need to use the Polymer transformers. |
| 598 You can test your app's JavaScript version using |
| 599 either Dart Editor's **Run as JavaScript** command |
| 600 or the `pub serve` command. |
| 601 To produce deployable files, |
| 602 use the `pub build` command. |
| 603 |
| 604 ###Specifying transformers |
| 605 |
| 606 Add a `transformers` entry to your app's `pubspec.yaml` file |
| 607 to specify the Polymer transformers: |
| 608 |
| 609 {% prettify yaml %} |
| 610 ... |
| 611 dependencies: |
| 612 polymer: ">=0.10.0 <0.11.0" |
| 613 transformers: |
| 614 - polymer |
| 615 {% endprettify %} |
| 616 |
| 617 By default, Polymer assumes that all HTML files under `web` can be |
| 618 _entry points_—files that define pages to be served, |
| 619 rather than elements to be included in pages. |
| 620 You can use an `entry_points` field to limit the HTML files that |
| 621 the Polymer transformers process. |
| 622 For example: |
| 623 |
| 624 {% prettify yaml %} |
| 625 ... |
| 626 transformers: |
| 627 - polymer: |
| 628 entry_points: web/index.html |
| 629 {% endprettify %} |
| 630 |
| 631 <aside class="alert alert-warning"> |
| 632 <b>Important:</b> |
| 633 YAML is whitespace-sensitive, |
| 634 so take care to indent the <tty>entry_points</tty> field as shown. |
| 635 </aside> |
| 636 |
| 637 For more information on using the Polymer transformers, see the |
| 638 [Polymer package documentation](http://pub.dartlang.org/packages/polymer). |
| 639 |
| 640 ###Testing the JavaScript version |
| 641 |
| 642 If you're using Dart Editor, |
| 643 you can test the JavaScript version in your default web browser |
| 644 by right-clicking your app's main file |
| 645 (for example, web/index.html) |
| 646 and choosing **Run as JavaScript**. |
| 647 Dart Editor runs the Polymer transformers, |
| 648 compiles your app to JavaScript, |
| 649 and opens a browser tab for your running app. |
| 650 You can copy the URL from that tab into any other browser |
| 651 that you'd like to test. |
| 652 |
| 653 Alternatively, run `pub serve` |
| 654 on the command line, |
| 655 from the app's top directory. |
| 656 That command runs the transformers |
| 657 and starts up an HTTP server to serve the app. |
| 658 The command's output gives you a URL that you can |
| 659 copy and paste into a browser window. |
| 660 If you change the app's files and reload the window, |
| 661 you see the updated version of the app. |
| 662 |
| 663 {% comment %} |
| 664 Update for 1.5, when Dart Editor will use pub serve more natively. |
| 665 What's the effect of that? |
| 666 Dart Editor already appears to run the polymer transformers. |
| 667 {% endcomment %} |
| 668 |
| 669 ###Generating JavaScript files |
| 670 |
| 671 When you're ready to generate files, |
| 672 run `pub build`—either at the command line or |
| 673 using Dart Editor—to |
| 674 generate the files your app needs |
| 675 to run in any modern browser. |
| 676 The generated files appear in the |
| 677 `build` directory, alongside your `pubspec.yaml` file. |
| 678 |
| 679 |
| 504 ##Other resources | 680 ##Other resources |
| 505 | 681 |
| 506 Use these other resources to learn more about Polymer: | 682 Use these other resources to learn more about Polymer: |
| 507 | 683 |
| 508 * The | 684 * The |
| 509 <a href="http://www.dartlang.org/polymer-dart/" | 685 <a href="http://www.dartlang.org/polymer-dart/" |
| 510 target="_blank">Polymer.dart</a> homepage provides information | 686 target="_blank">Polymer.dart</a> homepage provides information |
| 511 specific to the Dart port of the Polymer project. | 687 specific to the Dart port of the Polymer project. |
| 512 | 688 |
| 513 * The Polymer project website | 689 * The Polymer project website |
| (...skipping 16 matching lines...) Expand all Loading... |
| 530 | 706 |
| 531 The next tutorial, | 707 The next tutorial, |
| 532 [Fetch Data Dynamically](/docs/tutorials/fetchdata/), | 708 [Fetch Data Dynamically](/docs/tutorials/fetchdata/), |
| 533 shows you how to fetch data | 709 shows you how to fetch data |
| 534 and use JSON to encode and decode | 710 and use JSON to encode and decode |
| 535 that data. | 711 that data. |
| 536 | 712 |
| 537 {% endcapture %} | 713 {% endcapture %} |
| 538 | 714 |
| 539 {% include tutorial.html %} | 715 {% include tutorial.html %} |
| OLD | NEW |