Update everything
This commit is contained in:
parent
bf368181a4
commit
72a485d6e8
319 changed files with 67958 additions and 13948 deletions
216
lib/angular/docs/partials/guide/expression.html
Normal file
216
lib/angular/docs/partials/guide/expression.html
Normal file
|
@ -0,0 +1,216 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>Expressions are JavaScript-like code snippets that are usually placed in bindings such as <code>{{
|
||||
expression }}</code>. Expressions are processed by <a href="api/ng.$parse"><code>$parse</code></a>
|
||||
service.</p>
|
||||
|
||||
<p>For example, these are all valid expressions in angular:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>1+2</code></li>
|
||||
<li><code>3*10 | currency</code></li>
|
||||
<li><code>user.name</code></li>
|
||||
</ul>
|
||||
|
||||
<h3>Angular Expressions vs. JS Expressions</h3>
|
||||
|
||||
<p>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 <code>eval()</code> to evaluate expressions.
|
||||
You can think of Angular expressions as JavaScript expressions with following differences:</p>
|
||||
|
||||
<ul>
|
||||
<li><p><strong>Attribute Evaluation:</strong> evaluation of all properties are against the scope, doing the
|
||||
evaluation, unlike in JavaScript where the expressions are evaluated against the global
|
||||
<code>window</code>.</p></li>
|
||||
<li><p><strong>Forgiving:</strong> expression evaluation is forgiving to undefined and null, unlike in JavaScript,
|
||||
where such evaluations generate <code>NullPointerExceptions</code>.</p></li>
|
||||
<li><p><strong>No Control Flow Statements:</strong> you cannot do any of the following in angular expression:
|
||||
conditionals, loops, or throw.</p></li>
|
||||
<li><p><strong>Filters:</strong> you can pass result of expression evaluations through filter chains. For example
|
||||
to convert date object into a local specific human-readable format.</p></li>
|
||||
</ul>
|
||||
|
||||
<p>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 <code>eval()</code> an angular expression from
|
||||
JavaScript, use the <a href="api/ng.$rootScope.Scope#$eval"><code><code>$eval()</code></code></a> method.</p>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js" source-edit-html="index.html-50" source-edit-css="" source-edit-js="" source-edit-unit="" source-edit-scenario="scenario.js-51"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-50" ng-html-wrap=" angular.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-50">
|
||||
1+2={{1+2}}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-51"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-51">
|
||||
it('should calculate expression in binding', function() {
|
||||
expect(binding('1+2')).toEqual('3');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-50" ng-eval-javascript=""></div>
|
||||
|
||||
<p>You can try evaluating different expressions here:</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-53" source-edit-css="" source-edit-js="script.js-52" source-edit-unit="" source-edit-scenario="scenario.js-54"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-53" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-53">
|
||||
|
||||
<div ng-controller="Cntl2" class="expressions">
|
||||
Expression:
|
||||
<input type='text' ng-model="expr" size="80"/>
|
||||
<button ng-click="addExp(expr)">Evaluate</button>
|
||||
<ul>
|
||||
<li ng-repeat="expr in exprs">
|
||||
[ <a href="" ng-click="removeExp($index)">X</a> ]
|
||||
<tt>{{expr}}</tt> => <span ng-bind="$parent.$eval(expr)"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-52"></pre>
|
||||
<script type="text/ng-template" id="script.js-52">
|
||||
function Cntl2($scope) {
|
||||
var exprs = $scope.exprs = [];
|
||||
$scope.expr = '3*10|currency';
|
||||
$scope.addExp = function(expr) {
|
||||
exprs.push(expr);
|
||||
};
|
||||
|
||||
$scope.removeExp = function(index) {
|
||||
exprs.splice(index, 1);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-54"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-54">
|
||||
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"]);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-53" ng-eval-javascript="script.js-52"></div>
|
||||
|
||||
<h2>Property Evaluation</h2>
|
||||
|
||||
<p>Evaluation of all properties takes place against a scope. Unlike JavaScript, where names default
|
||||
to global window properties, Angular expressions have to use <a href="api/ng.$window"><code><code>$window</code></code></a> to refer to the global <code>window</code> object. For example, if you want to call <code>alert()</code>, which is
|
||||
defined on <code>window</code>, in an expression you must use <code>$window.alert()</code>. This is done intentionally to
|
||||
prevent accidental access to the global state (a common source of subtle bugs).</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-56" source-edit-css="" source-edit-js="script.js-55" source-edit-unit="" source-edit-scenario="scenario.js-57"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-56" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-56">
|
||||
|
||||
<div class="example2" ng-controller="Cntl1">
|
||||
Name: <input ng-model="name" type="text"/>
|
||||
<button ng-click="greet()">Greet</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-55"></pre>
|
||||
<script type="text/ng-template" id="script.js-55">
|
||||
function Cntl1($window, $scope){
|
||||
$scope.name = 'World';
|
||||
|
||||
$scope.greet = function() {
|
||||
($window.mockWindow || $window).alert('Hello ' + $scope.name);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-57"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-57">
|
||||
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');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-56" ng-eval-javascript="script.js-55"></div>
|
||||
|
||||
<h3>Forgiving</h3>
|
||||
|
||||
<p>Expression evaluation is forgiving to undefined and null. In JavaScript, evaluating <code>a.b.c</code> throws
|
||||
an exception if <code>a</code> 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:</p>
|
||||
|
||||
<pre><code> {{a.b.c}}
|
||||
</code></pre>
|
||||
|
||||
<p>It makes more sense to show nothing than to throw an exception if <code>a</code> 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: <code>{{((a||{}).b||{}).c}}</code></p>
|
||||
|
||||
<p>Similarly, invoking a function <code>a.b.c()</code> on undefined or null simply returns undefined.</p>
|
||||
|
||||
<h3>No Control Flow Statements</h3>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h3>Filters</h3>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<pre><code> name | uppercase
|
||||
</code></pre>
|
||||
|
||||
<p>The expression evaluator simply passes the value of name to <a href="api/ng.filter:uppercase"><code><code>uppercase</code></code></a> filter.</p>
|
||||
|
||||
<p>Chain filters using this syntax:</p>
|
||||
|
||||
<pre><code> value | filter1 | filter2
|
||||
</code></pre>
|
||||
|
||||
<p>You can also pass colon-delimited arguments to filters, for example, to display the number 123
|
||||
with 2 decimal points:</p>
|
||||
|
||||
<pre><code> 123 | number:2
|
||||
</code></pre>
|
||||
|
||||
<h2>The $</h2>
|
||||
|
||||
<p>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
|
||||
<code>a.length()</code> would return undefined because neither a nor angular define such a property.</p>
|
||||
|
||||
<p>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.</p></div>
|
Loading…
Add table
Add a link
Reference in a new issue