|
1 | | -# Expressions |
| 1 | +# Expressions and Statements |
| 2 | + |
| 3 | +Expressions and statements are small code snippets which are placed in the Angular templates. Following example shows where in the template can expressions and statements be located. |
| 4 | + |
| 5 | +``` |
| 6 | +<h1>{{expression}}</h1> |
| 7 | +<div [property1]="expression" property2="{{expression}}"> |
| 8 | +<button (click)="statement">OK</button> |
| 9 | +<div !foreach="#varName in expression">...</div> |
| 10 | +``` |
| 11 | + |
| 12 | +<table> |
| 13 | + <tr> |
| 14 | + <th></th> |
| 15 | + <th>Expressions</th> |
| 16 | + <th>Statements</th> |
| 17 | + </tr> |
| 18 | + <tr> |
| 19 | + <th>Used in:</th> |
| 20 | + <td>String in; Property binding; Template binding</td> |
| 21 | + <td>Events</td> |
| 22 | + </tr> |
| 23 | + <tr> |
| 24 | + <th>Execution</th> |
| 25 | + <td>During Change Detection</td> |
| 26 | + <td>Due to event before Change Detection</td> |
| 27 | + </tr> |
| 28 | + <tr> |
| 29 | + <th>Null dereference</th> |
| 30 | + <td>Forgiving / Silent</td> |
| 31 | + <td>Error</td> |
| 32 | + </tr> |
| 33 | + <tr> |
| 34 | + <th>Idempotent (side-effects)</th> |
| 35 | + <td>NO</td> |
| 36 | + <td>YES</td> |
| 37 | + </tr> |
| 38 | + <tr> |
| 39 | + <th>Assignments</th> |
| 40 | + <td>Not allowed</td> |
| 41 | + <td>Allowed</td> |
| 42 | + </tr> |
| 43 | + <tr> |
| 44 | + <th>Multiple</th> |
| 45 | + <td>Single expression</td> |
| 46 | + <td>Multiple statements separated by ';'</td> |
| 47 | + </tr> |
| 48 | + <tr> |
| 49 | + <th>Formatters</th> |
| 50 | + <td>Allowed at an end of expression only</td> |
| 51 | + <td>Not allowed</td> |
| 52 | + </tr> |
| 53 | +</table> |
| 54 | + |
| 55 | + |
| 56 | + |
| 57 | +## Expressions |
| 58 | + |
| 59 | +Expressions are bindings which are executed as part of the Change Detection. While Change Detection guarantees that the changes are delived in the order in which they are declared in the template, the individual sub-parts of the expressions may be executed in any order due to sub-expression coelescence. |
| 60 | + |
| 61 | +Example `<span>Hello: {{user.last}}, {{user.first}}</span>` is made up of `user`, `last`, and `first`. The change detection may chose to evaluate the `user` only once since it is a common sub-expression for the two expressions used in the binding. |
| 62 | + |
| 63 | +Expressions are forgiving in nature. In the above example if `user` is `null` the `user.last` will not throw an error, instead it will result in an `null` which will consequently be rendered as an empty string. This is done because during the data loading it is very common for sub-expressions to not be defined yet and placing guards around each expressions would result in too much boilerplate. |
| 64 | + |
| 65 | + |
| 66 | +### Expressions Semantics |
| 67 | + |
| 68 | +The expressions follow the semantics of the underlying platform with the exception of silent null dereferencing. This means that they follow JavaScript semantis in AngularJS, and Dart semantics in AngularDart. |
| 69 | + |
| 70 | +Some example of different semantics between JavaScript and Dart: |
| 71 | + |
| 72 | +- `'one' + 2`: will result in `one2` in JavaScript, but an error in Dart. |
| 73 | +- `obj['prop']`: will work for all objects in JavaScript, but only for `Map`s in Dart. (NOTE: ES6 `Map` require `obj.get('prop')`) |
| 74 | + |
| 75 | + |
| 76 | +### Expression Syntax |
| 77 | + |
| 78 | +Expression syntax follows that of the platform, with few limitations (no assignment and no keywords: `if`, `for`, etc) and additon of Formatters. |
| 79 | + |
| 80 | +Here is the list of allowed operations in Angular Expressions. |
| 81 | + |
| 82 | +<table> |
| 83 | + <tr> |
| 84 | + <th>Name</th> |
| 85 | + <th>Syntax</th> |
| 86 | + <th>Notes</th> |
| 87 | + </tr> |
| 88 | + <tr> |
| 89 | + <th>Dereference</th> |
| 90 | + <td>`obj.prop`</td> |
| 91 | + <td>Silently ignores if `obj` is `null` or `undefined`.</td> |
| 92 | + </tr> |
| 93 | + <tr> |
| 94 | + <th>Map</th> |
| 95 | + <td>`obj[key]`</td> |
| 96 | + <td>Silently ignores if `obj` is `null` or `undefined`. <br> JavaScript treats `obj.prop` and `obj['prop']` same, but Dart only allows `obj['prop']` on Maps.</td> |
| 97 | + </tr> |
| 98 | + <tr> |
| 99 | + <th>Operators:</th> |
| 100 | + <td>`+`, `-`, `/`, `*`, <br>`<`, `<=`, `<>`, `>=`, <br> `==`, `!=` <br> `!`</td> |
| 101 | + <td>JavaScript does type coercion, Dart requires types to match. </td> |
| 102 | + </tr> |
| 103 | + <tr> |
| 104 | + <th>Invocation</th> |
| 105 | + <td>`fn(args)`</td> |
| 106 | + <td></td> |
| 107 | + </tr> |
| 108 | + <tr> |
| 109 | + <th>Formatters</th> |
| 110 | + <td>expr | formatter:arg0:...</td> |
| 111 | + <td>Formatters must be at the end of the expression. The formatter arguments are separated by `:`, which in turn can be expressions. </td> |
| 112 | + </tr> |
| 113 | + <tr> |
| 114 | + <th>Truthyness</th> |
| 115 | + <td></td> |
| 116 | + <td>In Dart only values which are `Boolean` and `true` are consider truthy. In JavaScript type coercion allows many other things to be consider true.</td> |
| 117 | + </tr> |
| 118 | +</table> |
| 119 | + |
2 | 120 |
|
3 | | -## Binding Semantics |
4 | 121 |
|
5 | 122 | ### Formatters |
6 | 123 |
|
7 | | -## Statement Semantics |
| 124 | +Formatters are pure functions which can transform the input model to a different more usable data format. Examples include converting `Date` type to localized string or limiting the items in an array for filtering of `Foreach` items in a repeater. |
| 125 | + |
| 126 | +Formatters can only be placed at the end of an `expression` (i.e. they can not be part of sub-expressions.) Formatters can be chained together, where the output of one formatter becomes an input of the next. |
| 127 | + |
| 128 | +Formatters can take arguments, which are themselves an `expression`s separetd by `:`. |
| 129 | + |
| 130 | +Here are some examples: |
| 131 | + |
| 132 | +- `date | localizedDate` - Example of a formatter. |
| 133 | +- `date | localizedDate:'short'` - Example of a formatter takeing an argument. |
| 134 | +- `map | toArray | filter:predicate` - Example of formatter chaining. |
| 135 | + |
| 136 | + |
| 137 | +## Statement Semantics |
| 138 | + |
| 139 | +Statements execute in response to an event. Syntactically statements are identical to expressions with few differences: |
| 140 | + |
| 141 | +1. assignments are allowed |
| 142 | +2. `null` dereference is an error |
| 143 | +3. multiple statements separated by `;` |
| 144 | +4. Formatters are not allowed. |
| 145 | + |
| 146 | +<table> |
| 147 | + <tr> |
| 148 | + <th>Name</th> |
| 149 | + <th>Syntax</th> |
| 150 | + <th>Notes</th> |
| 151 | + </tr> |
| 152 | + <tr> |
| 153 | + <th>Dereference</th> |
| 154 | + <td>`obj.prop`, `obj[key]`</td> |
| 155 | + <td>Throws if `obj` is `null` or `undefined`.</td> |
| 156 | + </tr> |
| 157 | + <tr> |
| 158 | + <th>Assignment</th> |
| 159 | + <td>`=`</td> |
| 160 | + <td>Allowed in statements only.</td> |
| 161 | + </tr> |
| 162 | + <tr> |
| 163 | + <th>Formatters</th> |
| 164 | + <td></td> |
| 165 | + <td>Not allowed in statements.</td> |
| 166 | + </tr> |
| 167 | +</table> |
0 commit comments