欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Angular的表达式

程序员文章站 2022-06-08 12:00:15
...

Angular Expressions

Angular表达式

【原文】https://code.angularjs.org/1.2.23/docs/guide/expression

【翻译者】kowen@live.cn

https://code.angularjs.org/1.2.23/docs/guide/expression 写道
Angular expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}.
For example, these are valid expressions in Angular:

 Angular表达式是看起来和javascript类似的代码片段,通常是被放到双层大括号里:{{表达式}}。

例如,下面是一些有效的Angular表达式:

1+2
a+b
user.name
items[index]

 

Angular Expressions vs. JavaScript Expressions

 

Angular 表达式和 js表达式的对比

 

写道

 

Angular expressions are like JavaScript expressions with the following differences:

 Angular表达式和Javascript表达式非常相似,但有以下几点不同:

 

写道

 

Context: JavaScript expressions are evaluated against the global window. In Angular, expressions are evaluated against a scope object.

 上下文:Javascript表达式在全局窗口中起作用,Angular的表达式是在scope范围内中起作用。(不太恰当?)

 

写道

 

Forgiving: In JavaScript, trying to evaluate undefined properties generates ReferenceError or TypeError. In Angular, expression evaluation is forgiving to undefined and null.

 对出错宽大处理:Javascript计算含有未定义属性的表达式会产生ReferenceError或者TypeError,Angular 表达式允许计算含有未命名或者null的表达式。

 

写道

 

No Control Flow Statements: you cannot use the following in an Angular expression: conditionals, loops, or exceptions.

 禁止流程控制语句:Angular表达式中不能包含条件、循环或者异常语句。

 

写道

 

Filters: You can use filters within expressions to format data before displaying it.

 过滤器:你可以对Angular表达式进行格式化得到要显示的结果。

 

写道

 

If you want to run more complex JavaScript code, you should make it a controller method and call the method from your view. If you want to eval() an Angular expression yourself, use the $eval() method.

 如果需要运行比较复杂的Javascript语句,可以在控制器(controller)中创建一个方法,然后从视图(view)中去调用它。如果你想运行eval()计算angular表达式,你应当使用$eval()方法。

 

写道

 

You can try evaluating different expressions here:

 下面的例子可以计算各种表达式:

index.html

<div ng-controller="ExampleController" 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 track by $index">
     [ <a href="" ng-click="removeExp($index)">X</a> ]
     <tt>{{expr}}</tt> => <span ng-bind="$parent.$eval(expr)"></span>
    </li>
  </ul>
</div>

script.js

angular.module('expressionExample', [])
  .controller('ExampleController', ['$scope', function($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);
    };
  }]);

 

Context

 

上下文

 

写道

 

Angular does not use JavaScript's eval() to evaluate expressions. Instead Angular's $parse service processes these expressions.

 Angular不使用Javascript的eval()计算表达式的值,Angular有自己的$parse服务来计算表达式。

 

写道

 

Angular expressions do not have access to global variables like window, document or location. This restriction is intentional. It prevents accidental access to the global state – a common source of subtle bugs.

 Angular表达式没有访问window、doucument或者location这些全局变量的权限。这样做的目的是:防止不小心访问了相同名称的全局的变量,很多难以排除的bug都是这个原因引起的(应该是这个意思吧)。

 

写道

 

Instead use services like $window and $location in functions called from expressions. Such services provide mockable access to globals.

 那怎么访问global资源呢?有一个变通的方式:Angular表达式调用的function中,可以使用$window和$location等服务来访问global资源。例子:

index.html

<div class="example2" ng-controller="ExampleController">
  Name: <input ng-model="name" type="text"/>
  <button ng-click="greet()">Greet</button>
  <button ng-click="window.alert('Should not see me')">Won't greet</button>
</div>

 script.js

angular.module('expressionExample', [])
  .controller('ExampleController', ['$window', '$scope', function($window, $scope) {
    $scope.name = 'World';

    $scope.greet = function() {
      $window.alert('Hello ' + $scope.name);
    };
  }]);

 

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:

 Angular表达式求值对undefined和null都采取了宽大处理的态度。在Javascript中,如果a不是一个对象,那么a.b.c将会抛出一个异常。但是这个表达式本身是有意义的,它主要是用来作数据绑定的,例如

    {{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}}

 其实,这种情况与其抛出异常,不如直接啥也不显示(也许是正在等待服务器的相应,等一会就会变成defined了)。如果表达式不进行宽大处理的话,我们写的代码就乱套成这个样子了:{{((a||{}).b||{}).c}}

 

写道

 

Similarly, invoking a function a.b.c() on undefined or null simply returns undefined.

类似的,调用一个包含undefined或这null的function a.b.c(),返回值是undefined。

 

No Control Flow Statements

 

禁用流程控制语句

 

写道

 

Apart from the ternary operator (a ? b : c), 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 the views. If you need a real conditional, loop, or to throw from a view expression, delegate to a JavaScript method instead.

 除了三元运算符(a ? b : c),angular表达式中不允许使用流程控制语句。这么做的原因是Angular秉承着这样的思想:程序的逻辑部分应该在控制器中实现,不应该在视图中出现。如果在视图中必须使用条件、循环或者抛出异常,直接使用Javascript方法吧。

 

$event

事件对象

 

写道

 

Directives like ngClick and ngFocus expose a $event object within the scope of that expression.

 ngClick、ngFocus类似的指令会在表达式的有效范围内产生一个$event对象。

index.html

<div ng-controller="EventController">
  <button ng-click="clickMe($event)">Event</button>
  <p><code>$event</code>: <pre> {{$event | json}}</pre></p>
  <p><code>clickEvent</code>: <pre>{{clickEvent | json}}</pre></p>
</div>

 script.js

angular.module('eventExampleApp', []).
  controller('EventController', ['$scope', function($scope) {
    /*
     * expose the event object to the scope
     */
    $scope.clickMe = function(clickEvent) {
      $scope.clickEvent = simpleKeys(clickEvent);
      console.log(clickEvent);
    };

    /*
     * return a copy of an object with only non-object keys
     * we need this to avoid circular references
     */
    function simpleKeys (original) {
      return Object.keys(original).reduce(function (obj, key) {
        obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key];
        return obj;
      }, {});
    }
  }]);

 

 

写道

 

Note in the example above how we can pass in $event to clickMe, but how it does not show up in {{$event}}. This is because $event is outside the scope of that binding.

注意:这个例子中,$event对象可以传递到clickMe中显示,但是它却不能使用{{$event}}显示,因为$event是在这个绑定的scope之外(也就是$event只在ngClick指定的clickMe中存在)。