| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 polymer_expressions | 
|  | 2 =================== | 
|  | 3 | 
|  | 4 | 
|  | 5 Polymer expressions are an expressive syntax that can be used in HTML templates | 
|  | 6 with Dart. | 
|  | 7 | 
|  | 8 Templates are one feature of Polymer.dart, which is a set of comprehensive UI | 
|  | 9 and utility components for building web applications. | 
|  | 10 This package is automatically included with the | 
|  | 11 [Polymer](https://pub.dartlang.org/packages/polymer) package | 
|  | 12 because Polymer expressions are the default expression syntax | 
|  | 13 in Polymer Dart apps. | 
|  | 14 The [Polymer.dart homepage][home_page] | 
|  | 15 contains a list of features, project status, | 
|  | 16 installation instructions, tips for upgrading from Web UI, | 
|  | 17 and links to other documentation. | 
|  | 18 | 
|  | 19 | 
|  | 20 ## Overview | 
|  | 21 | 
|  | 22 Polymer expressions allow you to write complex binding expressions, with | 
|  | 23 property access, function invocation, list/map indexing, and two-way filtering | 
|  | 24 like: | 
|  | 25 | 
|  | 26 ```html | 
|  | 27     {{ person.title + " " + person.getFullName() | upppercase }} | 
|  | 28 ``` | 
|  | 29 | 
|  | 30 ### Model-Driven Views (MDV) | 
|  | 31 [MDV][mdv] allows you to define templates directly in HTML that are rendered by | 
|  | 32 the browser into the DOM. Templates are bound to a data model, and changes to | 
|  | 33 the data are automatically reflected in the DOM, and changes in HTML inputs are | 
|  | 34 assigned back into the model. The template and model are bound together via | 
|  | 35 binding expressions that are evaluated against the model. These binding | 
|  | 36 expressions are placed in double-curly-braces, or "mustaches". | 
|  | 37 | 
|  | 38 Example: | 
|  | 39 | 
|  | 40 ```html | 
|  | 41     <template> | 
|  | 42       <p>Hello {{ person.name }}</p> | 
|  | 43     </template> | 
|  | 44 ``` | 
|  | 45 | 
|  | 46 MDV includes a very basic binding syntax which only allows a series of | 
|  | 47 dot-separate property names. | 
|  | 48 | 
|  | 49 [mdv]: http://www.polymer-project.org/platform/mdv.html | 
|  | 50 | 
|  | 51 ### Custom binding syntaxes with binding delegate | 
|  | 52 | 
|  | 53 While MDV's built-in syntax is very basic, it does allow custom syntaxes called | 
|  | 54 "binding delegates" to be installed and used. A binding delegate can interpret | 
|  | 55 the contents of mustaches however it likes. PolymerExpressions is such a | 
|  | 56 binding delegate. | 
|  | 57 | 
|  | 58 Example: | 
|  | 59 | 
|  | 60 ```html | 
|  | 61     <template bind> | 
|  | 62       <p>Hello {{ person.title + " " + person.getFullName() | uppercase }}</p> | 
|  | 63     </template> | 
|  | 64 ``` | 
|  | 65 | 
|  | 66 ## Usage | 
|  | 67 | 
|  | 68 ### Installing from Pub | 
|  | 69 | 
|  | 70 Add the following to your pubspec.yaml file: | 
|  | 71 | 
|  | 72 ```yaml | 
|  | 73     dependencies: | 
|  | 74       polymer_expressions: any | 
|  | 75 ``` | 
|  | 76 | 
|  | 77 Hint: check https://pub.dartlang.org/packages/polymer_expressions for the latest | 
|  | 78 version number. | 
|  | 79 | 
|  | 80 Then import polymer_expressions.dart: | 
|  | 81 | 
|  | 82     import 'package:polymer_expressions/polymer_expressions.dart'; | 
|  | 83 | 
|  | 84 ### Registering a binding delegate | 
|  | 85 | 
|  | 86 **Polymer Expressions are now the default syntax for `<polymer-element>` custom | 
|  | 87 elements.** | 
|  | 88 | 
|  | 89 You do not need to manually register the bindingDelegate if your bindings are | 
|  | 90 inside a custom element. However, if you want to use polymer_expressions outside | 
|  | 91 a custom element, read on: | 
|  | 92 | 
|  | 93 Binding delegates must be installed on a template before they can be used. | 
|  | 94 For example, set the bindingDelegate property of your template | 
|  | 95 elements to an instance of PolymerExpressions. The templates will then use the | 
|  | 96 PolymerExpressions instance to interpret | 
|  | 97 binding expressions. | 
|  | 98 | 
|  | 99 ```dart | 
|  | 100     import 'dart:html'; | 
|  | 101     import 'package:polymer_expressions/polymer_expressions.dart'; | 
|  | 102 | 
|  | 103     main() { | 
|  | 104       var template = query('#my_template'); | 
|  | 105       template.bindingDelegate = new PolymerExpressions(); | 
|  | 106     } | 
|  | 107 ``` | 
|  | 108 | 
|  | 109 ### Registering top-level variables | 
|  | 110 | 
|  | 111 Before a top-level variable can be used, it must be registered. The | 
|  | 112 PolymerExpressions constructor takes a map of named values to use as variables. | 
|  | 113 | 
|  | 114 ```dart | 
|  | 115     main() { | 
|  | 116       var globals = { | 
|  | 117         'uppercase': (String v) => v.toUpperCase(), | 
|  | 118         'app_id': 'my_app_123', | 
|  | 119       }; | 
|  | 120       var template = query('#my_template'); | 
|  | 121       template.bindingDelegate = new PolymerExpressions(globals: globals); | 
|  | 122     } | 
|  | 123 ``` | 
|  | 124 | 
|  | 125 ## Features | 
|  | 126 | 
|  | 127 ### The model and scope | 
|  | 128 | 
|  | 129 Polymer Expressions allow binding to more than just the model assigned to a | 
|  | 130 template instance. Top-level variables can be defined so that you can use | 
|  | 131 filters, global variables and constants, functions, etc. These variables and the | 
|  | 132 model are held together in a container called a Scope. Scopes can be nested, | 
|  | 133 which happens when template tags are nested. | 
|  | 134 | 
|  | 135 ### Two-way bindings | 
|  | 136 | 
|  | 137 Bindings can be used to modify the data model based on events in the DOM. The | 
|  | 138 most common case is to bind an <input> element's value field to a model | 
|  | 139 property and have the property update when the input changes. For this to work, | 
|  | 140 the binding expression must be "assignable". Only a subset of expressions are | 
|  | 141 assignable. Assignable expressions cannot contain function calls, operators, and | 
|  | 142 any index operator must have a literal argument. Assignable expressions can | 
|  | 143 contain filter operators as long as all the filters are two-way transformers. | 
|  | 144 | 
|  | 145 Some restrictions may be relaxed further as allowed. | 
|  | 146 | 
|  | 147 Assignable Expressions: | 
|  | 148 | 
|  | 149  * `foo` | 
|  | 150  * `foo.bar` | 
|  | 151  * `items[0].description` | 
|  | 152  * `people['john'].name` | 
|  | 153  * `product.cost | convertCurrency('ZWD')` where `convertCurrency` evaluates to | 
|  | 154    a Tranformer object. | 
|  | 155 | 
|  | 156 Non-Assignable Expressions: | 
|  | 157 | 
|  | 158  * `a + 1` | 
|  | 159  * `!c` | 
|  | 160  * `foo()` | 
|  | 161  * `person.lastName | uppercase` where `uppercase` is a filter function. | 
|  | 162 | 
|  | 163 ### Null-Safety | 
|  | 164 | 
|  | 165 Expressions are generally null-safe. If an intermediate expression yields `null` | 
|  | 166 the entire expression will return null, rather than throwing an exception. | 
|  | 167 Property access, method invocation and operators are null-safe. Passing null to | 
|  | 168 a function that doesn't handle null will not be null safe. | 
|  | 169 | 
|  | 170 ### Streams | 
|  | 171 | 
|  | 172 Polymer Expressions have experimental support for binding to streams, and when | 
|  | 173 new values are passed to the stream, the template updates. The feature is not | 
|  | 174 fully implemented yet. | 
|  | 175 | 
|  | 176 See the examples in /example/streams for more details. | 
|  | 177 | 
|  | 178 ## Syntax | 
|  | 179 | 
|  | 180 ### Property access | 
|  | 181 | 
|  | 182 Properties on the model and in the scope are looked up via simple property | 
|  | 183 names, like `foo`. Property names are looked up first in the top-level | 
|  | 184 variables, next in the model, then recursively in parent scopes. Properties on | 
|  | 185 objects can be access with dot notation like `foo.bar`. | 
|  | 186 | 
|  | 187 The keyword `this` always refers to the model if there is one, otherwise `this` | 
|  | 188 is `null`. If you have model properties and top-level variables with the same | 
|  | 189 name, you can use `this` to refer to the model property. | 
|  | 190 | 
|  | 191 ### Literals | 
|  | 192 | 
|  | 193 Polymer Expressions support number, boolean, string, and map literals. Strings | 
|  | 194 can use either single or double quotes. | 
|  | 195 | 
|  | 196  * Numbers: `1`, `1.0` | 
|  | 197  * Booleans: `true`, `false` | 
|  | 198  * Strings: `'abc'`, `"xyz"` | 
|  | 199  * Maps: `{ 'a': 1, 'b': 2 }` | 
|  | 200 | 
|  | 201 List literals are planned, see [issue 9](https://github.com/dart-lang/polymer_ex
     pressions/issues/9) | 
|  | 202 | 
|  | 203 ### Functions and methods | 
|  | 204 | 
|  | 205 If a property is a function in the scope, a method on the model, or a method on | 
|  | 206 an object, it can be invoked with standard function syntax. Functions and | 
|  | 207 Methods can take arguments. Named arguments are not supported. Arguments can be | 
|  | 208 literals or variables. | 
|  | 209 | 
|  | 210 Examples: | 
|  | 211 | 
|  | 212  * Top-level function: `myFunction()` | 
|  | 213  * Top-level function with arguments: `myFunction(a, b, 42)` | 
|  | 214  * Model method: `aMethod()` | 
|  | 215  * Method on nested-property: `a.b.anotherMethod()` | 
|  | 216 | 
|  | 217 ### Operators | 
|  | 218 | 
|  | 219 Polymer Expressions supports the following binary and unary operators: | 
|  | 220 | 
|  | 221  * Arithmetic operators: +, -, *, /, %, unary + and - | 
|  | 222  * Comparison operators: ==, !=, <=, <, >, >= | 
|  | 223  * Boolean operators: &&, ||, unary ! | 
|  | 224 | 
|  | 225 Expressions do not support bitwise operators such as &, |, << and >>, or increme
     nt/decrement operators (++ and --) | 
|  | 226 | 
|  | 227 ### List and Map indexing | 
|  | 228 | 
|  | 229 List and Map like objects can be accessed via the index operator: [] | 
|  | 230 | 
|  | 231 Examples: | 
|  | 232 | 
|  | 233  * `items[2]` | 
|  | 234  * `people['john']` | 
|  | 235 | 
|  | 236 Unlike JavaScript, list and map contents are not generally available via | 
|  | 237 property access. That is, the previous examples are not equivalent to `items.2` | 
|  | 238 and `people.john`. This ensures that access to properties and methods on Lists | 
|  | 239 and Maps is preserved. | 
|  | 240 | 
|  | 241 ### Filters and transformers | 
|  | 242 | 
|  | 243 A filter is a function that transforms a value into another, used via the pipe | 
|  | 244 syntax: `value | filter` Any function that takes exactly one argument can be | 
|  | 245 used as a filter. | 
|  | 246 | 
|  | 247 Example: | 
|  | 248 | 
|  | 249 If `person.name` is "John", and a top-level function named `uppercase` has been | 
|  | 250 registered, then `person.name | uppercase` will have the value "JOHN". | 
|  | 251 | 
|  | 252 The pipe syntax is used rather than a regular function call so that we can | 
|  | 253 support two-way bindings through transformers. A transformer is a filter that | 
|  | 254 has an inverse function. Transformers must extend or implement the `Transformer` | 
|  | 255 class, which has `forward()` and `reverse()` methods. | 
|  | 256 | 
|  | 257 ### Repeating templates | 
|  | 258 | 
|  | 259 A template can be repeated by using the "repeat" attribute with a binding. The | 
|  | 260 binding can either evaluate to an Iterable, in which case the template is | 
|  | 261 instantiated for each item in the iterable and the model of the instance is | 
|  | 262 set to the item, or the binding can be a "in" iterator expression, in which | 
|  | 263 case a new variable is added to each scope. | 
|  | 264 | 
|  | 265 The following examples produce the same output. | 
|  | 266 | 
|  | 267 Evaluate to an iterable: | 
|  | 268 | 
|  | 269 ```html | 
|  | 270     <template repeat="{{ items }}"> | 
|  | 271       <div>{{ }}</div> | 
|  | 272     </template> | 
|  | 273 ``` | 
|  | 274 | 
|  | 275 "in" expression: | 
|  | 276 | 
|  | 277 ```html | 
|  | 278     <template repeat="{{ item in items }}"> | 
|  | 279       <div>{{ item }}</div> | 
|  | 280     </template> | 
|  | 281 ``` | 
|  | 282 | 
|  | 283 ## Status | 
|  | 284 | 
|  | 285 The syntax implemented is experimental and subject to change, in fact, it | 
|  | 286 **will** change soon. The goal is to be compatible with Polymer's binding | 
|  | 287 syntax. We will announce breaking changes on the | 
|  | 288 [web-ui@dartlang.org mailing list][web-ui-list]. | 
|  | 289 | 
|  | 290 Please [file issues on Dart project page](http://dartbug.com/new) | 
|  | 291 for any bugs you find or for feature requests. Make a note that it applies to | 
|  | 292 "package:polymer_expressions" | 
|  | 293 | 
|  | 294 You can discuss Polymer Expressions on the | 
|  | 295 [web-ui@dartlang.org mailing list][web-ui-list]. | 
|  | 296 | 
|  | 297 [web-ui-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/web-ui | 
| OLD | NEW | 
|---|