diff options
| author | Igor Minar | 2011-06-06 22:02:30 -0700 | 
|---|---|---|
| committer | Igor Minar | 2011-06-06 23:10:30 -0700 | 
| commit | c35b0a7907de1535269876668c345ce944681804 (patch) | |
| tree | a3ba548369ca65db790809197196ae946cc93a18 /docs/content/guide/expression.ngdoc | |
| parent | 805bb5bb6e5842a5760976a446074d553609f5b6 (diff) | |
| download | angular.js-c35b0a7907de1535269876668c345ce944681804.tar.bz2 | |
yet another docs batch
Diffstat (limited to 'docs/content/guide/expression.ngdoc')
| -rw-r--r-- | docs/content/guide/expression.ngdoc | 207 | 
1 files changed, 0 insertions, 207 deletions
| diff --git a/docs/content/guide/expression.ngdoc b/docs/content/guide/expression.ngdoc deleted file mode 100644 index 421dd9c7..00000000 --- a/docs/content/guide/expression.ngdoc +++ /dev/null @@ -1,207 +0,0 @@ -@workInProgress -@ngdoc overview -@name Developer Guide: Expression -@description - -# Expressions -Expressions are the bindings that you write in HTML and embed in templates in order to create -views in angular. They are 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 you want to run arbitrary JavaScript code, make it a controller method and call that. If you -want to eval an angular expression from JavaScript, use the Scope:$eval() method. - -## Example -<doc:example> - <doc:source> -  1+2={{1+2}} - </doc:source> - <doc:scenario> -  it('should calculate expression in binding', function(){ -    expect(binding('1+2')).toEqual('3'); -  }); - </doc:scenario> -</doc:example> - -You can try evaluating different expressions here: - -<doc:example> - <doc:source> -  <div ng:init="exprs=[]" class="expressions"> -    Expression: -    <input type='text' name="expr" value="3*10|currency" size="80"/> -    <button ng:click="exprs.$add(expr)">Evaluate</button> -    <ul> -     <li ng:repeat="expr in exprs"> -       [ <a href="" ng:click="exprs.$remove(expr)">X</a> ] -       <tt>{{expr}}</tt> => <span ng:bind="$parent.$eval(expr)"></span> -      </li> -    </ul> -  </div> - </doc:source> - <doc:scenario> -  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"]); -  }); - </doc:scenario> -</doc:example> - -# Attribute Evaluation - -Evaluation of all attributes are 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. E.g. 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). - -<doc:example> - <doc:source> -  <div class="example2" ng:init="$window = $service('$window')"> -    Name: <input name="name" type="text" value="World"/> -    <button ng:click="($window.mockWindow || $window).alert('Hello ' + name)">Greet</button> -  </div> - </doc:source> - <doc:scenario> -  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'); -  }); - </doc:scenario> -</doc:example> - -## 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 (e.g. 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 $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.Array.filter(). You can call -it from JavaScript. - -Extensions: You can further extend the expression vocabulary by adding new methods to -`angular.Array` or `angular.String`, etc. - -<doc:example> - <doc:source> -  <div ng:init="friends = [ -    {name:'John', phone:'555-1212'}, -    {name:'Mary', phone:'555-9876'}, -    {name:'Mike', phone:'555-4321'}, -    {name:'Adam', phone:'555-5678'}, -    {name:'Julie', phone:'555-8765'}]"></div> -  Search: <input name="searchText"/> -  <table class="example3"> -    <tr><th>Name</th><th>Phone</th><tr> -    <tr ng:repeat="friend in friends.$filter(searchText)"> -      <td>{{friend.name}}</td> -      <td>{{friend.phone}}</td> -    </tr> -  </table> - </doc:source> - <doc:scenario> -  it('should filter the list', function(){ -     var tr = using('table.example3').repeater('tr.ng-attr-widget'); -     expect(tr.count()).toBe(5); -     input('searchText').enter('a'); -     expect(tr.count()).toBe(2); - -  }); - </doc:scenario> -</doc:example> - -## 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: - -<pre> -name | uppercase -</pre> - -The expression evaluator simply passes the value of name to angular.filter.uppercase. - -Chain filters using this syntax: - -<pre> -value | filter1 | filter2 -</pre> - -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 chooses 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 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. - - | 
