1
1
@ngdoc overview
2
- @name Developer Guide: Understanding Angular Expressions
2
+ @name Developer Guide: Expressions
3
3
@description
4
4
5
- Expressions are {@link dev_guide.templates.databinding bindings} that you write in HTML and embed
6
- in templates in order to create views in angular. Angular expressions are similar but not
7
- equivalent to JavaScript expressions .
5
+ Expressions are JavaScript-like code snippets that are usually placed in bindings such as `{{
6
+ expression }}`. Expressions are process by the {@link api/ angular.module.ng.$parse $parse}
7
+ service .
8
8
9
9
For example, these are all valid expressions in angular:
10
10
11
- * `1+2={{1+2}}`
12
- * `3*10|currency`
13
- * `Hello {{name}}!`
14
- * `Hello {{'World'}}!`
11
+ * `1+2`
12
+ * `3*10 | currency`
13
+ * `user.name`
15
14
16
15
17
16
## Angular Expressions vs. JS Expressions
18
17
19
18
It might be tempting to think of angular view expressions as JavaScript expressions, but that is
20
- not entirely correct. Angular does not use a simple JavaScript eval of the expression text. You can
21
- think of angular expressions as JavaScript expressions with these differences:
22
-
23
- * **Attribute Evaluation:** evaluation of all attributes are against the current scope, not to the
24
- global window as in JavaScript.
25
- * **Forgiving:** expression evaluation is forgiving to undefined and null, unlike in JavaScript.
26
- * **No Control Flow Statements:** you cannot do the following from an angular expression:
27
- conditionals, loops, or throw.
28
- * **Type Augmentation:** the scope expression evaluator augments built-in types.
29
- * **Filters:** you can add filters to an expression, for example to convert raw data into a
30
- human-readable format.
31
- * **The $:** angular reserves this prefix to differentiate its API names from others.
19
+ not entirely correct, since angular does not use a JavaScript `eval()` to evaluate expressions.
20
+ You can think of angular expressions as JavaScript expressions with following differences
21
+ differences:
22
+
23
+ * **Attribute Evaluation:** evaluation of all properties are against the scope, doing the
24
+ evaluation, unlike in JavaScript where the expressions are evaluated against the global
25
+ `window`.
26
+
27
+ * **Forgiving:** expression evaluation is forgiving to undefined and null, unlike in JavaScript,
28
+ where such evaluations generate `NullPointerExceptions`.
29
+
30
+ * **No Control Flow Statements:** you cannot do any of the following in angular expression:
31
+ conditionals, loops, or throw.
32
+
33
+ * **Filters:** you can pass result of expression evaluations through filter chains. For example
34
+ to convert date object into a local specific human-readable format.
32
35
33
36
If, on the other hand, you do want to run arbitrary JavaScript code, you should make it a
34
- controller method and call that . If you want to `eval()` an angular expression from JavaScript, use
35
- the ` Scope: $eval()` method.
37
+ controller method and call the method . If you want to `eval()` an angular expression from
38
+ JavaScript, use the {@link api/angular.module.ng.$rootScope. Scope# $eval `$eval ()`} method.
36
39
37
40
## Example
38
41
<doc:example>
@@ -86,13 +89,13 @@ You can try evaluating different expressions here:
86
89
</doc:example>
87
90
88
91
89
- # Attribute Evaluation
92
+ # Property Evaluation
90
93
91
- Evaluation of all attributes takes place against the current scope. Unlike JavaScript, where names
92
- default to global window properties, angular expressions have to use ` $window` to refer to the
93
- global object. For example, if you want to call `alert()`, which is defined on `window`, an
94
- expression must use `$window.alert()`. This is done intentionally to prevent accidental access to
95
- the global state (a common source of subtle bugs).
94
+ Evaluation of all properties takes place against a scope. Unlike JavaScript, where names default
95
+ to global window properties, angular expressions have to use {@link api/angular.module.ng. $window
96
+ `$window`} to refer to the global `window` object. For example, if you want to call `alert()`, which is
97
+ defined on `window`, in an expression must use `$window.alert()`. This is done intentionally to
98
+ prevent accidental access to the global state (a common source of subtle bugs).
96
99
97
100
<doc:example>
98
101
<doc:source>
@@ -141,67 +144,13 @@ forgiving we'd have to write bindings that clutter the code, for example: `{{((a
141
144
142
145
Similarly, invoking a function `a.b.c()` on undefined or null simply returns undefined.
143
146
144
- Assignments work the same way in reverse:
145
-
146
- a.b.c = 10
147
-
148
- ...creates the intermediary objects even if a is undefined.
149
-
150
147
151
148
## No Control Flow Statements
152
149
153
150
You cannot write a control flow statement in an expression. The reason behind this is core to the
154
151
angular philosophy that application logic should be in controllers, not in the view. If you need a
155
- conditional (including ternary operators), loop, or to throw from a view expression, delegate to a
156
- JavaScript method instead.
157
-
158
-
159
- ## Type Augmentation
160
-
161
- Built-in types have methods like `[].push()`, but the richness of these methods is limited.
162
- Consider the example below, which allows you to do a simple search over a canned set of contacts.
163
- The example would be much more complicated if we did not have the `Array:$filter()`. There is no
164
- built-in method on `Array` called {@link api/angular.module.ng.$filter.filter $filter} and angular doesn't add
165
- it to `Array.prototype` because that could collide with other JavaScript frameworks.
166
-
167
- For this reason the scope expression evaluator augments the built-in types to make them act like
168
- they have extra methods. The actual method for `$filter()` is `angular.module.ng.$filter.filter()`. You can
169
- call it from JavaScript.
170
-
171
- Extensions: You can further extend the expression vocabulary by adding new methods to
172
- `angular.module.ng.$filter` or `angular.String`, etc.
152
+ conditional, loop, or to throw from a view expression, delegate to a JavaScript method instead.
173
153
174
- <doc:example>
175
- <doc:source>
176
- <div ng-init="friends = [
177
- {name:'John', phone:'555-1212'},
178
- {name:'Mary', phone:'555-9876'},
179
- {name:'Mike', phone:'555-4321'},
180
- {name:'Adam', phone:'555-5678'},
181
- {name:'Julie', phone:'555-8765'}]"></div>
182
- Search: <input ng-model="searchText"/>
183
- <table class="example3">
184
- <thead>
185
- <tr><th>Name</th><th>Phone</th><tr>
186
- </thead>
187
- <tbody>
188
- <tr ng-repeat="friend in friends | filter:searchText">
189
- <td>{{friend.name}}</td>
190
- <td>{{friend.phone}}</td>
191
- </tr>
192
- </tbody>
193
- </table>
194
- </doc:source>
195
- <doc:scenario>
196
- it('should filter the list', function() {
197
- var tr = using('table.example3 tbody').repeater('tr');
198
- expect(tr.count()).toBe(5);
199
- input('searchText').enter('a');
200
- expect(tr.count()).toBe(2);
201
-
202
- });
203
- </doc:scenario>
204
- </doc:example>
205
154
206
155
## Filters
207
156
@@ -212,14 +161,15 @@ of filters like this:
212
161
213
162
name | uppercase
214
163
215
- The expression evaluator simply passes the value of name to angular.module.ng.$filter.uppercase.
164
+ The expression evaluator simply passes the value of name to {@link
165
+ api/angular.module.ng.$filter.uppercase `uppercase`} filter.
216
166
217
167
Chain filters using this syntax:
218
168
219
169
value | filter1 | filter2
220
170
221
- You can also pass colon-delimited arguments to filters, for example, to display the number 123 with
222
- 2 decimal points:
171
+ You can also pass colon-delimited arguments to filters, for example, to display the number 123
172
+ with 2 decimal points:
223
173
224
174
123 | number:2
225
175
@@ -235,11 +185,3 @@ property and then we would have a collision. This problem exists because angular
235
185
objects with additional behavior. By prefixing its additions with $ we are reserving our namespace
236
186
so that angular developers and developers who use angular can develop in harmony without collisions.
237
187
238
-
239
- ## Related Topics
240
-
241
- * {@link dev_guide.templates.filters Understanding Angular Filters}
242
-
243
- ## Related API
244
-
245
- * {@link api/angular.module.ng.$compile Angular Compiler API}
0 commit comments