| OLD | NEW |
| 1 --- | 1 --- |
| 2 layout: article | 2 layout: article |
| 3 title: "Web UI Specification" | 3 title: "Web UI Specification" |
| 4 rel: | 4 rel: |
| 5 author: siggi-cherem | 5 author: siggi-cherem |
| 6 description: "A detailed reference guide of how to use Web UI for declarative mo
dern web apps." | 6 description: "A detailed reference guide of how to use Web UI for declarative mo
dern web apps." |
| 7 has-permalinks: true | 7 has-permalinks: true |
| 8 --- | 8 --- |
| 9 {% comment %} | 9 {% comment %} |
| 10 | 10 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 <aside> | 92 <aside> |
| 93 <div class="alert alert-info"> | 93 <div class="alert alert-info"> |
| 94 <strong>Status:</strong> It should be allowed to declare element tags anywhere, | 94 <strong>Status:</strong> It should be allowed to declare element tags anywhere, |
| 95 not just in the body of an HTML page. See | 95 not just in the body of an HTML page. See |
| 96 <a href="https://github.com/dart-lang/web-ui/issues/197">Issue | 96 <a href="https://github.com/dart-lang/web-ui/issues/197">Issue |
| 97 #197</a> for details. | 97 #197</a> for details. |
| 98 </div> | 98 </div> |
| 99 </aside> | 99 </aside> |
| 100 | 100 |
| 101 #### Appearance | 101 #### Appearance |
| 102 {:.no_toc} |
| 102 | 103 |
| 103 Every component inherits from existing tags. | 104 Every component inherits from existing tags. |
| 104 This includes tags corresponding to | 105 This includes tags corresponding to |
| 105 standard DOM elements or previously defined components. For example, you can | 106 standard DOM elements or previously defined components. For example, you can |
| 106 extend `div`, `span`, `button`, `x-my-button`, etc. The base tag for the | 107 extend `div`, `span`, `button`, `x-my-button`, etc. The base tag for the |
| 107 component is specified in the `extends` attribute. The idea is that a component | 108 component is specified in the `extends` attribute. The idea is that a component |
| 108 can override and compose the appearance and behavior of its base tag. It is a | 109 can override and compose the appearance and behavior of its base tag. It is a |
| 109 common practice to use `span` as the base tag if you intend to define the | 110 common practice to use `span` as the base tag if you intend to define the |
| 110 entire appearance of a component yourself. | 111 entire appearance of a component yourself. |
| 111 | 112 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 138 <div class="alert alert-info"> | 139 <div class="alert alert-info"> |
| 139 <strong>NOTE:</strong> scoped <code>style</code> is not supported yet in the | 140 <strong>NOTE:</strong> scoped <code>style</code> is not supported yet in the |
| 140 current implementation of the the Web UI compiler, and a lot of details are | 141 current implementation of the the Web UI compiler, and a lot of details are |
| 141 missing in this specification. Learn more at the <a | 142 missing in this specification. Learn more at the <a |
| 142 href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#st
yles">web | 143 href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#st
yles">web |
| 143 components specification article</a>. | 144 components specification article</a>. |
| 144 </div> | 145 </div> |
| 145 </aside> | 146 </aside> |
| 146 | 147 |
| 147 #### Behavior | 148 #### Behavior |
| 149 {:.no_toc} |
| 148 | 150 |
| 149 The behavior of a component is declared directly in Dart code. The `<script>` | 151 The behavior of a component is declared directly in Dart code. The `<script>` |
| 150 tag declares the code associated with the component. | 152 tag declares the code associated with the component. |
| 151 It must be specified unless | 153 It must be specified unless |
| 152 a component has no behavior and its code can be assumed to be an empty class. | 154 a component has no behavior and its code can be assumed to be an empty class. |
| 153 If the tag is present, it must use the `type="application/dart"` attribute to | 155 If the tag is present, it must use the `type="application/dart"` attribute to |
| 154 indicate that the code is written in Dart. | 156 indicate that the code is written in Dart. |
| 155 | 157 |
| 156 Whether you write code inline or you include it via a `src` attribute, the code | 158 Whether you write code inline or you include it via a `src` attribute, the code |
| 157 must be a valid Dart library. In such a library you must define a class | 159 must be a valid Dart library. In such a library you must define a class |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 interactive element, such as input boxes and text areas. | 360 interactive element, such as input boxes and text areas. |
| 359 | 361 |
| 360 If data bindings are used within a component, the associated Dart expressions | 362 If data bindings are used within a component, the associated Dart expressions |
| 361 are resolved in the scope of the class associated with the component (see more | 363 are resolved in the scope of the class associated with the component (see more |
| 362 details [above](#template-scope)). If data bindings are used directly on | 364 details [above](#template-scope)). If data bindings are used directly on |
| 363 the body of an HTML page, these expressions are evaluated in the context of the | 365 the body of an HTML page, these expressions are evaluated in the context of the |
| 364 main script associated with that page (more details | 366 main script associated with that page (more details |
| 365 [later](#top-level-templates)). | 367 [later](#top-level-templates)). |
| 366 | 368 |
| 367 #### Binding in content | 369 #### Binding in content |
| 370 {:.no_toc} |
| 368 | 371 |
| 369 You can introduce a data binding in a text node | 372 You can introduce a data binding in a text node |
| 370 by using expressions of the form | 373 by using expressions of the form |
| 371 `{{'{{'}}exp}}` as nodes in your HTML. For example, a component with the | 374 `{{'{{'}}exp}}` as nodes in your HTML. For example, a component with the |
| 372 following template: | 375 following template: |
| 373 | 376 |
| 374 {% prettify html %} | 377 {% prettify html %} |
| 375 {% raw %} | 378 {% raw %} |
| 376 <element name='x-example2'> | 379 <element name='x-example2'> |
| 377 <template><span>one {{x}} tree</span></template> | 380 <template><span>one {{x}} tree</span></template> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 398 than what you initially intended to happen. | 401 than what you initially intended to happen. |
| 399 | 402 |
| 400 The program generated by the Web UI compiler will evaluate a | 403 The program generated by the Web UI compiler will evaluate a |
| 401 binding expression to a value, call [`toString()`][tostring] on it and place | 404 binding expression to a value, call [`toString()`][tostring] on it and place |
| 402 the result as a text node where the binding was found. This means that if your | 405 the result as a text node where the binding was found. This means that if your |
| 403 content has some HTML tags in it, the content is automatically escaped. For | 406 content has some HTML tags in it, the content is automatically escaped. For |
| 404 instance, if we use `x='<span>two</span>'`, the result will be `<span>one | 407 instance, if we use `x='<span>two</span>'`, the result will be `<span>one |
| 405 <span>two</span> three</span>` | 408 <span>two</span> three</span>` |
| 406 | 409 |
| 407 On occasions, you may want to inject HTML fragments directly in the page. | 410 On occasions, you may want to inject HTML fragments directly in the page. |
| 408 You can do so by creating an instance of `SafeHtml` (see | 411 You can do so by creating an instance of `SafeHtml` (see |
| 409 [`package:web_ui/safe_html.dart`][safehtml]). If your content happen to | 412 [`package:web_ui/safe_html.dart`][safehtml]). If your content happen to |
| 410 be an instance of `SafeHtml`, then the data will not be escaped. | 413 be an instance of `SafeHtml`, then the data will not be escaped. |
| 411 | 414 |
| 412 **Note:** Use `SafeHtml` carefully. In particular, you can easily | 415 **Note:** Use `SafeHtml` carefully. In particular, you can easily |
| 413 make your application exploitable through cross-site scripting (XSS) attacks if | 416 make your application exploitable through cross-site scripting (XSS) attacks if |
| 414 you allow arbitrary user data to be placed unescaped in your page. In practice, | 417 you allow arbitrary user data to be placed unescaped in your page. In practice, |
| 415 you should only use it when you know that the HTML is valid and safe. | 418 you should only use it when you know that the HTML is valid and safe. |
| 416 | 419 |
| 417 <aside> | 420 <aside> |
| 418 <div class="alert alert-info"> | 421 <div class="alert alert-info"> |
| 419 <strong>Status:</strong> `SafeHtml` is available but very primitive at this | 422 <strong>Status:</strong> `SafeHtml` is available but very primitive at this |
| 420 point. This type should evolve, | 423 point. This type should evolve, |
| 421 and maybe one day it could be integrated as part | 424 and maybe one day it could be integrated as part |
| 422 of the `dart:html` APIs. | 425 of the `dart:html` APIs. |
| 423 </div> | 426 </div> |
| 424 </aside> | 427 </aside> |
| 425 | 428 |
| 426 #### Binding in attributes | 429 #### Binding in attributes |
| 430 {:.no_toc} |
| 427 | 431 |
| 428 You can also use `{{'{{'}}expression}}` bindings in the middle of HTML | 432 You can also use `{{'{{'}}expression}}` bindings in the middle of HTML |
| 429 attributes. An attribute written as `foo="{{'{{'}}exp}}"` will be initialized | 433 attributes. An attribute written as `foo="{{'{{'}}exp}}"` will be initialized |
| 430 with the value of `exp`. Like bindings in content nodes, expressions are | 434 with the value of `exp`. Like bindings in content nodes, expressions are |
| 431 [watched](#watchers) for changes and attributes will be updated in place when | 435 [watched](#watchers) for changes and attributes will be updated in place when |
| 432 expressions' changes are detected. At runtime, attribute values will be updated | 436 expressions' changes are detected. At runtime, attribute values will be updated |
| 433 using an assignment directly on the HTML element property corresponding to that | 437 using an assignment directly on the HTML element property corresponding to that |
| 434 attribute. Bindings of the form `attribute="{{'{{'}}exp}}"` are assigned | 438 attribute. Bindings of the form `attribute="{{'{{'}}exp}}"` are assigned |
| 435 directly, however bindings of the form `attribute="abc {{'{{'}}exp}} xyc"` will | 439 directly, however bindings of the form `attribute="abc {{'{{'}}exp}} xyc"` will |
| 436 perform string interpolation. | 440 perform string interpolation. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 </element> | 507 </element> |
| 504 {% endraw %} | 508 {% endraw %} |
| 505 {% endprettify %} | 509 {% endprettify %} |
| 506 | 510 |
| 507 | 511 |
| 508 * style attributes: you can pass either a `String` or a `Map<String, String>` as | 512 * style attributes: you can pass either a `String` or a `Map<String, String>` as |
| 509 a binding to `style` attributes. When using a map, we track changes to | 513 a binding to `style` attributes. When using a map, we track changes to |
| 510 the map keys and values and update actual style of the element accordingly. | 514 the map keys and values and update actual style of the element accordingly. |
| 511 | 515 |
| 512 #### Binding interactive elements | 516 #### Binding interactive elements |
| 517 {:.no_toc} |
| 513 | 518 |
| 514 Bindings can also be used to monitor user modifications on interactive elements, | 519 Bindings can also be used to monitor user modifications on interactive elements, |
| 515 such as input boxes, text areas, and radio buttons. We do so by binding an | 520 such as input boxes, text areas, and radio buttons. We do so by binding an |
| 516 interactive element with a Dart assignable value, such as a field or a property | 521 interactive element with a Dart assignable value, such as a field or a property |
| 517 with a getter and setter. Unlike the bindings we discussed above, these bindings | 522 with a getter and setter. Unlike the bindings we discussed above, these bindings |
| 518 operate in two directions: changes in the Dart value are reflected in the UI, | 523 operate in two directions: changes in the Dart value are reflected in the UI, |
| 519 but also changes from the user in the UI are reflected directly in the Dart | 524 but also changes from the user in the UI are reflected directly in the Dart |
| 520 value. Because of their bidirectional nature, we refer to these bindings as | 525 value. Because of their bidirectional nature, we refer to these bindings as |
| 521 _two-way data bindings_. Two-way data bindings are expressed with an attribute | 526 _two-way data bindings_. Two-way data bindings are expressed with an attribute |
| 522 of the form `bind-property="assignableValue"`, where _property_ is the | 527 of the form `bind-property="assignableValue"`, where _property_ is the |
| 523 associated property in the HTML element that we are monitoring, and | 528 associated property in the HTML element that we are monitoring, and |
| 524 _assignableValue_ is a Dart assignable value. This is the current list of | 529 _assignableValue_ is a Dart assignable value. This is the current list of |
| 525 two-way bindings supported by Web UI: | 530 two-way bindings supported by Web UI: |
| 526 | 531 |
| 527 | | Interactive element | | Attribute | | Description
| | Event that triggers an update | | 532 | | Interactive element | | Attribute | | Description
| | Event that triggers an update | |
| 528 |-| :----------- |- | :-------- |- | :-------
|- | :------ | | 533 |-| :----------- |- | :-------- |- | :-------
|- | :------ | |
| 529 | | `<textarea>` | | `value` | | The current value in t
he textarea element | | `input` | | 534 | | `<textarea>` | | `value` | | The current value in t
he textarea element | | `input` | |
| 530 | | `<input type="text">` | | `value` | | The current value in t
he input box | | `input` | | 535 | | `<input type="text">` | | `value` | | The current value in t
he input box | | `input` | |
| 531 | | `<input type="checkbox">` | | `checked` | | Whether the checkbox i
s checked | | `change` | | 536 | | `<input type="checkbox">` | | `checked` | | Whether the checkbox i
s checked | | `change` | |
| 532 | | `<input type="radio">` | | `checked` | | Whether a radio button
is checked | | `change` | | 537 | | `<input type="radio">` | | `checked` | | Whether a radio button
is checked | | `change` | |
| 533 | | `<input name="group" type="radio" value="option">` | | `value`
| | Whether a value matches the radio button's value | | `change` | | 538 | | `<input name="group" type="radio" value="option">` | | `value`
| | Whether a value matches the radio button's value | | `change` | |
| 534 | | `<select>` | | `selected-index`| | Selected option index
on the dropdown list | | `change` | | 539 | | `<select>` | | `selected-index`| | Selected option index
on the dropdown list | | `change` | |
| 535 | | `<select>` | | `value` | | Selected option value
on the dropdown list | | `change` | | 540 | | `<select>` | | `value` | | Selected option value
on the dropdown list | | `change` | |
| 536 |=| =============== |= | ========= |= | ========
|= | == | | 541 |=| =============== |= | ========= |= | ========
|= | == | |
| 537 | 542 |
| 538 Under the hood two-way bindings are implemented by using a [watcher](#watchers) | 543 Under the hood two-way bindings are implemented by using a [watcher](#watchers) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 | 580 |
| 576 <aside> | 581 <aside> |
| 577 <div class="alert alert-info"> | 582 <div class="alert alert-info"> |
| 578 <strong>Status:</strong> More interactive elements need to be supported. | 583 <strong>Status:</strong> More interactive elements need to be supported. |
| 579 </div> | 584 </div> |
| 580 </aside> | 585 </aside> |
| 581 | 586 |
| 582 | 587 |
| 583 | 588 |
| 584 #### Watchers | 589 #### Watchers |
| 590 {:.no_toc} |
| 585 | 591 |
| 586 As hinted in the previous sections, data bindings are reactive. We would like | 592 As hinted in the previous sections, data bindings are reactive. We would like |
| 587 the UI to be updated automatically whenever a Dart expression used in a data | 593 the UI to be updated automatically whenever a Dart expression used in a data |
| 588 binding changes. Watchers provide a way to implement this functionality. Their | 594 binding changes. Watchers provide a way to implement this functionality. Their |
| 589 implementation is available under `package:web_ui/watcher.dart`. For | 595 implementation is available under `package:web_ui/watcher.dart`. For |
| 590 each expression used in a data binding, we create a watcher. These watchers are | 596 each expression used in a data binding, we create a watcher. These watchers are |
| 591 inactive until the special method `dispatch` in the watcher's library is | 597 inactive until the special method `dispatch` in the watcher's library is |
| 592 invoked. The `dispatch` method will iterate over all active watchers and fire | 598 invoked. The `dispatch` method will iterate over all active watchers and fire |
| 593 events on any watcher whose value has changed. | 599 events on any watcher whose value has changed. |
| 594 | 600 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 619 | 625 |
| 620 Portions of the template can be conditionally hidden using template | 626 Portions of the template can be conditionally hidden using template |
| 621 conditionals. Web UI supports two different ways to express conditionals. You | 627 conditionals. Web UI supports two different ways to express conditionals. You |
| 622 can make a document fragment conditionally visible by declaring it within a | 628 can make a document fragment conditionally visible by declaring it within a |
| 623 conditional `<template>` element node, or you can make an element and its | 629 conditional `<template>` element node, or you can make an element and its |
| 624 children conditionally visible by using a conditional attribute | 630 children conditionally visible by using a conditional attribute |
| 625 in the element. Next, we discuss each of these approaches and when it is | 631 in the element. Next, we discuss each of these approaches and when it is |
| 626 appropriate to [use one or the other](#which-conditional). | 632 appropriate to [use one or the other](#which-conditional). |
| 627 | 633 |
| 628 #### The conditional element node {#conditional-template} | 634 #### The conditional element node {#conditional-template} |
| 635 {:.no_toc} |
| 629 | 636 |
| 630 A template conditional element is a `<template>` tag containing a special | 637 A template conditional element is a `<template>` tag containing a special |
| 631 attribute of the form `instantiate="if expression"`, where `expression` is a | 638 attribute of the form `instantiate="if expression"`, where `expression` is a |
| 632 valid Dart expression, just like any [data binding expression](#data-binding). | 639 valid Dart expression, just like any [data binding expression](#data-binding). |
| 633 Alternatively, instead of `instantiate="if exp"` you can write `if="exp"`. | 640 Alternatively, instead of `instantiate="if exp"` you can write `if="exp"`. |
| 634 | 641 |
| 635 <aside> | 642 <aside> |
| 636 <div class="alert alert-info"> | 643 <div class="alert alert-info"> |
| 637 <strong>Note:</strong> | 644 <strong>Note:</strong> |
| 638 The final syntax for conditionals is not finalized. In particular, currently | 645 The final syntax for conditionals is not finalized. In particular, currently |
| 639 only <code>instantiate="if ..."</code> is part of the MDV specification. | 646 only <code>instantiate="if ..."</code> is part of the MDV specification. |
| 640 However, Web UI supports both <code>instantiate="if ..."</code> and | 647 However, Web UI supports both <code>instantiate="if ..."</code> and |
| 641 <code>if="..."</code> and it will later provide feedback whenever one is | 648 <code>if="..."</code> and it will later provide feedback whenever one is |
| 642 deprecated in favor of the other. | 649 deprecated in favor of the other. |
| 643 </div> | 650 </div> |
| 644 </aside> | 651 </aside> |
| 645 | 652 |
| 646 Consider this concrete example: | 653 Consider this concrete example: |
| 647 | 654 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 </div> | 694 </div> |
| 688 here | 695 here |
| 689 Unconditional portion 2 | 696 Unconditional portion 2 |
| 690 {% endprettify %} | 697 {% endprettify %} |
| 691 | 698 |
| 692 Note that the contents of the initial template are not within the template | 699 Note that the contents of the initial template are not within the template |
| 693 tag anymore, they got added directly as siblings. This behavior is | 700 tag anymore, they got added directly as siblings. This behavior is |
| 694 intentional. Template nodes are intended to be inert, and they are mainly used | 701 intentional. Template nodes are intended to be inert, and they are mainly used |
| 695 as a declaration. This matches closely the semantics of [MDV][mdv] templates. | 702 as a declaration. This matches closely the semantics of [MDV][mdv] templates. |
| 696 | 703 |
| 697 A benefit of this semantics is that the resulting HTML is often closer to | 704 A benefit of this semantics is that the resulting HTML is often closer to |
| 698 what the developer intended to say. For example, a template of the form: | 705 what the developer intended to say. For example, a template of the form: |
| 699 | 706 |
| 700 {% prettify html %} | 707 {% prettify html %} |
| 701 <ul> | 708 <ul> |
| 702 <li> item 1 | 709 <li> item 1 |
| 703 <template instantiate="if showItem2"> | 710 <template instantiate="if showItem2"> |
| 704 <li> item 2 | 711 <li> item 2 |
| 705 </template> | 712 </template> |
| 706 </ul> | 713 </ul> |
| 707 {% endprettify %} | 714 {% endprettify %} |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 {% prettify html %} | 749 {% prettify html %} |
| 743 {% raw %} | 750 {% raw %} |
| 744 <element name='x-example'> | 751 <element name='x-example'> |
| 745 <!-- invalid: we need an extra template here. --> | 752 <!-- invalid: we need an extra template here. --> |
| 746 <template instantiate="if true">this is invalid</template> | 753 <template instantiate="if true">this is invalid</template> |
| 747 </element> | 754 </element> |
| 748 {% endraw %} | 755 {% endraw %} |
| 749 {% endprettify %} | 756 {% endprettify %} |
| 750 | 757 |
| 751 #### The conditional attribute. {#conditional-attribute} | 758 #### The conditional attribute. {#conditional-attribute} |
| 759 {:.no_toc} |
| 752 | 760 |
| 753 An alternative syntax to create conditional content is to use a conditional | 761 An alternative syntax to create conditional content is to use a conditional |
| 754 attribute on an arbitrary element. This is especially useful in contexts where | 762 attribute on an arbitrary element. This is especially useful in contexts where |
| 755 you are not allowed to insert a `<template>` element (such as tables). | 763 you are not allowed to insert a `<template>` element (such as tables). |
| 756 | 764 |
| 757 You can express a conditional by adding two attributes to any element, an empty | 765 You can express a conditional by adding two attributes to any element, an empty |
| 758 `template` attribute, and a `instantiate="if ..."` attribute. For example, in | 766 `template` attribute, and a `instantiate="if ..."` attribute. For example, in |
| 759 the following code, `item 2` will only be visible if `showItem2` is true. | 767 the following code, `item 2` will only be visible if `showItem2` is true. |
| 760 | 768 |
| 761 {% prettify html %} | 769 {% prettify html %} |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 | 809 |
| 802 <aside> | 810 <aside> |
| 803 <div class="alert alert-info"> | 811 <div class="alert alert-info"> |
| 804 <strong>Note:</strong> These semantics might change in the near future. The | 812 <strong>Note:</strong> These semantics might change in the near future. The |
| 805 placeholder in this case seems redundant when the condition is true - we could | 813 placeholder in this case seems redundant when the condition is true - we could |
| 806 simply reuse the placeholder node to render the contents within it. | 814 simply reuse the placeholder node to render the contents within it. |
| 807 </div> | 815 </div> |
| 808 </aside> | 816 </aside> |
| 809 | 817 |
| 810 #### Conditional element vs. attribute {#which-conditional} | 818 #### Conditional element vs. attribute {#which-conditional} |
| 819 {:.no_toc} |
| 811 | 820 |
| 812 The main difference between conditional template nodes and conditional | 821 The main difference between conditional template nodes and conditional |
| 813 attributes is that the former makes the contents of the template node | 822 attributes is that the former makes the contents of the template node |
| 814 conditionally visible, while the latter makes the actual node conditionally | 823 conditionally visible, while the latter makes the actual node conditionally |
| 815 visible. | 824 visible. |
| 816 | 825 |
| 817 This difference is especially noticeable when making plain text nodes | 826 This difference is especially noticeable when making plain text nodes |
| 818 conditionally visible. For example, the following template: | 827 conditionally visible. For example, the following template: |
| 819 | 828 |
| 820 {% prettify html %} | 829 {% prettify html %} |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 | 886 |
| 878 Loops make it possible to iterate over a collection and repeat portions of a | 887 Loops make it possible to iterate over a collection and repeat portions of a |
| 879 template with each iteration. Just like [conditionals](#conditionals), | 888 template with each iteration. Just like [conditionals](#conditionals), |
| 880 there are | 889 there are |
| 881 also 2 ways to express loops. | 890 also 2 ways to express loops. |
| 882 You can repeat a fragment by declaring it within a | 891 You can repeat a fragment by declaring it within a |
| 883 iterate `<template>` element node, or you can repeat the body of an element by | 892 iterate `<template>` element node, or you can repeat the body of an element by |
| 884 using an iterate attribute on the element. | 893 using an iterate attribute on the element. |
| 885 | 894 |
| 886 #### The iterate element node {#iterate-template} | 895 #### The iterate element node {#iterate-template} |
| 896 {:.no_toc} |
| 887 | 897 |
| 888 A template iterate element is a `<template>` tag containing a special attribute | 898 A template iterate element is a `<template>` tag containing a special attribute |
| 889 of the form `iterate="identifier in expression"`, where `expression` evaluates | 899 of the form `iterate="identifier in expression"`, where `expression` evaluates |
| 890 to a collection, and `identifier` is a new variable that will be visible to the | 900 to a collection, and `identifier` is a new variable that will be visible to the |
| 891 body of the iterate element. For instance, in the following example: | 901 body of the iterate element. For instance, in the following example: |
| 892 | 902 |
| 893 {% prettify html %} | 903 {% prettify html %} |
| 894 {% raw %} | 904 {% raw %} |
| 895 <ul> | 905 <ul> |
| 896 <li> header | 906 <li> header |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 <li> footer | 940 <li> footer |
| 931 </ul> | 941 </ul> |
| 932 {% endprettify %} | 942 {% endprettify %} |
| 933 | 943 |
| 934 See the sections above on [conditionals](#conditionals) for more details on why | 944 See the sections above on [conditionals](#conditionals) for more details on why |
| 935 children of the template node are appended directly as siblings of the | 945 children of the template node are appended directly as siblings of the |
| 936 placeholder node, and to understand what implications this has during app | 946 placeholder node, and to understand what implications this has during app |
| 937 development. | 947 development. |
| 938 | 948 |
| 939 #### The iterate attribute {#iterate-attribute} | 949 #### The iterate attribute {#iterate-attribute} |
| 950 {:.no_toc} |
| 940 | 951 |
| 941 An alternative syntax to do template iterations is | 952 An alternative syntax to do template iterations is |
| 942 to use an `iterate` attribute | 953 to use an `iterate` attribute |
| 943 directly on an element. This is especially useful to iterate on table rows or | 954 directly on an element. This is especially useful to iterate on table rows or |
| 944 columns, where you are not allowed to use `<template>` tags. | 955 columns, where you are not allowed to use `<template>` tags. |
| 945 | 956 |
| 946 The runtime semantics of iterate attributes are different than iterate template | 957 The runtime semantics of iterate attributes are different than iterate template |
| 947 nodes. The placeholder node and the iteration element are basically the same. | 958 nodes. The placeholder node and the iteration element are basically the same. |
| 948 The node is always present, but its contents are modified depending on the | 959 The node is always present, but its contents are modified depending on the |
| 949 values found in the collection. For example, the following template: | 960 values found in the collection. For example, the following template: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 972 {% endprettify %} | 983 {% endprettify %} |
| 973 | 984 |
| 974 <aside> | 985 <aside> |
| 975 <div class="alert alert-info"> | 986 <div class="alert alert-info"> |
| 976 <strong>Note:</strong> In the future a single attribute will be enough, we | 987 <strong>Note:</strong> In the future a single attribute will be enough, we |
| 977 intent to remove the extra <code>template</code> attribute. | 988 intent to remove the extra <code>template</code> attribute. |
| 978 </div> | 989 </div> |
| 979 </aside> | 990 </aside> |
| 980 | 991 |
| 981 #### Iterate element vs. attribute {#which-loop} | 992 #### Iterate element vs. attribute {#which-loop} |
| 993 {:.no_toc} |
| 982 | 994 |
| 983 The main difference between iterate template nodes and iterate attributes is | 995 The main difference between iterate template nodes and iterate attributes is |
| 984 that the former appends the repeated contents | 996 that the former appends the repeated contents |
| 985 as siblings of the iteration node, | 997 as siblings of the iteration node, |
| 986 while the latter appends them as children of | 998 while the latter appends them as children of |
| 987 the element containing the iterate attribute. | 999 the element containing the iterate attribute. |
| 988 | 1000 |
| 989 This difference is especially noticeable when you want to create a list with a | 1001 This difference is especially noticeable when you want to create a list with a |
| 990 header and a footer. This is supported by template nodes as follows: | 1002 header and a footer. This is supported by template nodes as follows: |
| 991 | 1003 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1166 [dart-scope-rules]: http://www.dartlang.org/docs/spec/latest/dart-language-speci
fication.html#h.jb82efuudrc5 | 1178 [dart-scope-rules]: http://www.dartlang.org/docs/spec/latest/dart-language-speci
fication.html#h.jb82efuudrc5 |
| 1167 [project]: https://github.com/dart-lang/web-ui/ | 1179 [project]: https://github.com/dart-lang/web-ui/ |
| 1168 [mdv]: http://code.google.com/p/mdv/ | 1180 [mdv]: http://code.google.com/p/mdv/ |
| 1169 [sd]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html | 1181 [sd]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html |
| 1170 [shadow-el]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.
html#shadow-element | 1182 [shadow-el]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.
html#shadow-element |
| 1171 [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html | 1183 [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html |
| 1172 [wcappendix]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.h
tml#appendix-b-html-elements | 1184 [wcappendix]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.h
tml#appendix-b-html-elements |
| 1173 [tostring]: http://api.dartlang.org/docs/bleeding_edge/dart_core/Object.html#toS
tring | 1185 [tostring]: http://api.dartlang.org/docs/bleeding_edge/dart_core/Object.html#toS
tring |
| 1174 [safehtml]: https://github.com/dart-lang/web-ui/blob/master/lib/safe_html.dart | 1186 [safehtml]: https://github.com/dart-lang/web-ui/blob/master/lib/safe_html.dart |
| 1175 [elemevents]: http://api.dartlang.org/docs/releases/latest/dart_html/Element.htm
l | 1187 [elemevents]: http://api.dartlang.org/docs/releases/latest/dart_html/Element.htm
l |
| OLD | NEW |