From 41d26db32c1c013dd33faa03df85e38681a9ebb1 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 28 Feb 2012 14:29:58 -0800
Subject: docs(expression): rewrite
---
docs/content/guide/dev_guide.expressions.ngdoc | 245 -------------------------
docs/content/guide/expression.ngdoc | 187 +++++++++++++++++++
2 files changed, 187 insertions(+), 245 deletions(-)
delete mode 100644 docs/content/guide/dev_guide.expressions.ngdoc
create mode 100644 docs/content/guide/expression.ngdoc
(limited to 'docs/content')
diff --git a/docs/content/guide/dev_guide.expressions.ngdoc b/docs/content/guide/dev_guide.expressions.ngdoc
deleted file mode 100644
index c54a9343..00000000
--- a/docs/content/guide/dev_guide.expressions.ngdoc
+++ /dev/null
@@ -1,245 +0,0 @@
-@ngdoc overview
-@name Developer Guide: Understanding Angular Expressions
-@description
-
-Expressions are {@link dev_guide.templates.databinding bindings} that you write in HTML and embed
-in templates in order to create views in angular. Angular expressions are similar but not
-equivalent to JavaScript expressions.
-
-For example, these are all valid expressions in angular:
-
-* `1+2={{1+2}}`
-* `3*10|currency`
-* `Hello {{name}}!`
-* `Hello {{'World'}}!`
-
-
-## Angular Expressions vs. JS Expressions
-
-It might be tempting to think of angular view expressions as JavaScript expressions, but that is
-not entirely correct. Angular does not use a simple JavaScript eval of the expression text. You can
-think of angular expressions as JavaScript expressions with these differences:
-
-* **Attribute Evaluation:** evaluation of all attributes are against the current scope, not to the
-global window as in JavaScript.
-* **Forgiving:** expression evaluation is forgiving to undefined and null, unlike in JavaScript.
-* **No Control Flow Statements:** you cannot do the following from an angular expression:
-conditionals, loops, or throw.
-* **Type Augmentation:** the scope expression evaluator augments built-in types.
-* **Filters:** you can add filters to an expression, for example to convert raw data into a
-human-readable format.
-* **The $:** angular reserves this prefix to differentiate its API names from others.
-
-If, on the other hand, you do want to run arbitrary JavaScript code, you should make it a
-controller method and call that. If you want to `eval()` an angular expression from JavaScript, use
-the `Scope:$eval()` method.
-
-## Example
-
-
- 1+2={{1+2}}
-
-
- it('should calculate expression in binding', function() {
- expect(binding('1+2')).toEqual('3');
- });
-
-
-
-You can try evaluating different expressions here:
-
-
-
-
-
-
-
- it('should allow user expression testing', function() {
- element('.expressions :button').click();
- var li = using('.expressions ul').repeater('li');
- expect(li.count()).toBe(1);
- expect(li.row(0)).toEqual(["3*10|currency", "$30.00"]);
- });
-
-
-
-
-# Attribute Evaluation
-
-Evaluation of all attributes takes place against the current scope. Unlike JavaScript, where names
-default to global window properties, angular expressions have to use `$window` to refer to the
-global object. For example, if you want to call `alert()`, which is defined on `window`, an
-expression must use `$window.alert()`. This is done intentionally to prevent accidental access to
-the global state (a common source of subtle bugs).
-
-
-
-
-
- Name:
-
-
-
-
- it('should calculate expression in binding', function() {
- var alertText;
- this.addFutureAction('set mock', function($window, $document, done) {
- $window.mockWindow = {
- alert: function(text){ alertText = text; }
- };
- done();
- });
- element(':button:contains(Greet)').click();
- expect(this.addFuture('alert text', function(done) {
- done(null, alertText);
- })).toBe('Hello World');
- });
-
-
-
-## Forgiving
-
-Expression evaluation is forgiving to undefined and null. In JavaScript, evaluating `a.b.c` throws
-an exception if `a` is not an object. While this makes sense for a general purpose language, the
-expression evaluations are primarily used for data binding, which often look like this:
-
- {{a.b.c}}
-
-It makes more sense to show nothing than to throw an exception if `a` is undefined (perhaps we are
-waiting for the server response, and it will become defined soon). If expression evaluation wasn't
-forgiving we'd have to write bindings that clutter the code, for example: `{{((a||{}).b||{}).c}}`
-
-Similarly, invoking a function `a.b.c()` on undefined or null simply returns undefined.
-
-Assignments work the same way in reverse:
-
- a.b.c = 10
-
-...creates the intermediary objects even if a is undefined.
-
-
-## No Control Flow Statements
-
-You cannot write a control flow statement in an expression. The reason behind this is core to the
-angular philosophy that application logic should be in controllers, not in the view. If you need a
-conditional (including ternary operators), loop, or to throw from a view expression, delegate to a
-JavaScript method instead.
-
-
-## Type Augmentation
-
-Built-in types have methods like `[].push()`, but the richness of these methods is limited.
-Consider the example below, which allows you to do a simple search over a canned set of contacts.
-The example would be much more complicated if we did not have the `Array:$filter()`. There is no
-built-in method on `Array` called {@link api/angular.module.ng.$filter.filter $filter} and angular doesn't add
-it to `Array.prototype` because that could collide with other JavaScript frameworks.
-
-For this reason the scope expression evaluator augments the built-in types to make them act like
-they have extra methods. The actual method for `$filter()` is `angular.module.ng.$filter.filter()`. You can
-call it from JavaScript.
-
-Extensions: You can further extend the expression vocabulary by adding new methods to
-`angular.module.ng.$filter` or `angular.String`, etc.
-
-
-
-
- Search:
-
-
-
Name
Phone
-
-
-
-
{{friend.name}}
-
{{friend.phone}}
-
-
-
-
-
- it('should filter the list', function() {
- var tr = using('table.example3 tbody').repeater('tr');
- expect(tr.count()).toBe(5);
- input('searchText').enter('a');
- expect(tr.count()).toBe(2);
-
- });
-
-
-
-## Filters
-
-When presenting data to the user, you might need to convert the data from its raw format to a
-user-friendly format. For example, you might have a data object that needs to be formatted
-according to the locale before displaying it to the user. You can pass expressions through a chain
-of filters like this:
-
- name | uppercase
-
-The expression evaluator simply passes the value of name to angular.module.ng.$filter.uppercase.
-
-Chain filters using this syntax:
-
- value | filter1 | filter2
-
-You can also pass colon-delimited arguments to filters, for example, to display the number 123 with
-2 decimal points:
-
- 123 | number:2
-
-# The $
-
-You might be wondering, what is the significance of the $ prefix? It is simply a prefix that
-angular uses, to differentiate its API names from others. If angular didn't use $, then evaluating
-`a.length()` would return undefined because neither a nor angular define such a property.
-
-Consider that in a future version of angular we might choose to add a length method, in which case
-the behavior of the expression would change. Worse yet, you the developer could create a length
-property and then we would have a collision. This problem exists because angular augments existing
-objects with additional behavior. By prefixing its additions with $ we are reserving our namespace
-so that angular developers and developers who use angular can develop in harmony without collisions.
-
-
-## Related Topics
-
-* {@link dev_guide.templates.filters Understanding Angular Filters}
-
-## Related API
-
-* {@link api/angular.module.ng.$compile Angular Compiler API}
diff --git a/docs/content/guide/expression.ngdoc b/docs/content/guide/expression.ngdoc
new file mode 100644
index 00000000..f92dbe48
--- /dev/null
+++ b/docs/content/guide/expression.ngdoc
@@ -0,0 +1,187 @@
+@ngdoc overview
+@name Developer Guide: Expressions
+@description
+
+Expressions are JavaScript-like code snippets that are usually placed in bindings such as `{{
+expression }}`. Expressions are process by the {@link api/angular.module.ng.$parse $parse}
+service.
+
+For example, these are all valid expressions in angular:
+
+ * `1+2`
+ * `3*10 | currency`
+ * `user.name`
+
+
+## Angular Expressions vs. JS Expressions
+
+It might be tempting to think of angular view expressions as JavaScript expressions, but that is
+not entirely correct, since angular does not use a JavaScript `eval()` to evaluate expressions.
+You can think of angular expressions as JavaScript expressions with following differences
+differences:
+
+ * **Attribute Evaluation:** evaluation of all properties are against the scope, doing the
+ evaluation, unlike in JavaScript where the expressions are evaluated against the global
+ `window`.
+
+ * **Forgiving:** expression evaluation is forgiving to undefined and null, unlike in JavaScript,
+ where such evaluations generate `NullPointerExceptions`.
+
+ * **No Control Flow Statements:** you cannot do any of the following in angular expression:
+ conditionals, loops, or throw.
+
+ * **Filters:** you can pass result of expression evaluations through filter chains. For example
+ to convert date object into a local specific human-readable format.
+
+If, on the other hand, you do want to run arbitrary JavaScript code, you should make it a
+controller method and call the method. If you want to `eval()` an angular expression from
+JavaScript, use the {@link api/angular.module.ng.$rootScope.Scope#$eval `$eval()`} method.
+
+## Example
+
+
+ 1+2={{1+2}}
+
+
+ it('should calculate expression in binding', function() {
+ expect(binding('1+2')).toEqual('3');
+ });
+
+
+
+You can try evaluating different expressions here:
+
+
+
+
+
+
+
+ it('should allow user expression testing', function() {
+ element('.expressions :button').click();
+ var li = using('.expressions ul').repeater('li');
+ expect(li.count()).toBe(1);
+ expect(li.row(0)).toEqual(["3*10|currency", "$30.00"]);
+ });
+
+
+
+
+# Property Evaluation
+
+Evaluation of all properties takes place against a scope. Unlike JavaScript, where names default
+to global window properties, angular expressions have to use {@link api/angular.module.ng.$window
+`$window`} to refer to the global `window` object. For example, if you want to call `alert()`, which is
+defined on `window`, in an expression must use `$window.alert()`. This is done intentionally to
+prevent accidental access to the global state (a common source of subtle bugs).
+
+
+
+
+
+ Name:
+
+
+
+
+ it('should calculate expression in binding', function() {
+ var alertText;
+ this.addFutureAction('set mock', function($window, $document, done) {
+ $window.mockWindow = {
+ alert: function(text){ alertText = text; }
+ };
+ done();
+ });
+ element(':button:contains(Greet)').click();
+ expect(this.addFuture('alert text', function(done) {
+ done(null, alertText);
+ })).toBe('Hello World');
+ });
+
+
+
+## Forgiving
+
+Expression evaluation is forgiving to undefined and null. In JavaScript, evaluating `a.b.c` throws
+an exception if `a` is not an object. While this makes sense for a general purpose language, the
+expression evaluations are primarily used for data binding, which often look like this:
+
+ {{a.b.c}}
+
+It makes more sense to show nothing than to throw an exception if `a` is undefined (perhaps we are
+waiting for the server response, and it will become defined soon). If expression evaluation wasn't
+forgiving we'd have to write bindings that clutter the code, for example: `{{((a||{}).b||{}).c}}`
+
+Similarly, invoking a function `a.b.c()` on undefined or null simply returns undefined.
+
+
+## No Control Flow Statements
+
+You cannot write a control flow statement in an expression. The reason behind this is core to the
+angular philosophy that application logic should be in controllers, not in the view. If you need a
+conditional, loop, or to throw from a view expression, delegate to a JavaScript method instead.
+
+
+## Filters
+
+When presenting data to the user, you might need to convert the data from its raw format to a
+user-friendly format. For example, you might have a data object that needs to be formatted
+according to the locale before displaying it to the user. You can pass expressions through a chain
+of filters like this:
+
+ name | uppercase
+
+The expression evaluator simply passes the value of name to {@link
+api/angular.module.ng.$filter.uppercase `uppercase`} filter.
+
+Chain filters using this syntax:
+
+ value | filter1 | filter2
+
+You can also pass colon-delimited arguments to filters, for example, to display the number 123
+with 2 decimal points:
+
+ 123 | number:2
+
+# The $
+
+You might be wondering, what is the significance of the $ prefix? It is simply a prefix that
+angular uses, to differentiate its API names from others. If angular didn't use $, then evaluating
+`a.length()` would return undefined because neither a nor angular define such a property.
+
+Consider that in a future version of angular we might choose to add a length method, in which case
+the behavior of the expression would change. Worse yet, you the developer could create a length
+property and then we would have a collision. This problem exists because angular augments existing
+objects with additional behavior. By prefixing its additions with $ we are reserving our namespace
+so that angular developers and developers who use angular can develop in harmony without collisions.
+
--
cgit v1.2.3