原版地址:http://code.angularjs.org/1.0.2/docs/guide/expression

表达式(Expressions)是类Javascript的代码片段,通常放置在绑定区域中(如{{expression}})。表达式通过$parse服务(http://code.angularjs.org/1.0.2/docs/api/ng.$parse)解析执行。

  例如,以下是angular中有效的表达式:

  • 1+2
  • 3*10 | currency
  • user.name

一、Angular表达式 vs. Js 表达式

  这很容易让人将angular视图表达式联想为javascript表达式,但这并不完全正确,因为angular不是通过javascript的eval()对表达式进行求值。你可以将angular表达式想象为带有以下差异的javascript表达式:

  • 属性求值:所有属性的求值是对于scope的,而javascript是对于window对象的。
  • 宽容(forgiving):表达式求值,对于undefined和null,angular是宽容的,但Javascript会产生NullPointerExceptions(-_-!!!!怎么我没见过)。
  • 没有流程控制语句:在angular表达式里,我们不能做以下任何的事:条件分支、循环、抛出异常。
  • 过滤器(filters):我们可以就将表达式的结果传入过滤器链(filter chains)。例如将日期对象转换为本地指定的人类可读的格式。

  另一方面,如果我们想(在angular表达式中)执行任意的Javascript代码,我们可以将那些代码写到Controller的一个方法中并调用它。如果我们想在javascript中eval()一个angular表达式,可以使用$eval()方法。

 
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="ExpressionTest">
<head>
<meta charset="UTF-8">
<title>expression-e1</title>
<style type="text/css">
.ng-cloak {
display: none;
}
</style>
</head>
<body ng-controller="MyCtrl">
1 + 2 = {{1+2}}
<br/>
Expression:
<input type="text" ng-model="expr"/>
<button ng-click="addExp(expr)">Evaluate</button>
<ul>
<li ng-repeat="expr in exprs">
[<a ng-click="removeExp($index)" href="">X</a>]
<tt>{{expr}}</tt>=><span ng-bind="$parent.$eval(expr)"></span>
</li>
</ul>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
var app = angular.module("ExpressionTest", []);
app.controller("MyCtrl", 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);
};
});
</script>
</body>
</html>
 

二、属性求值(Property Evaluation)

  angular的表达式解析环境的上下文是scope,而javascript则是window(应该是指严格模式evel的时候),angular需要通过$window访问global window对象。例如,如果我们需要在表达式中调用定义在window对象上的alert(),我们需要使用$window.alert()。这样做的用意是避免意外访问了公共属性(global state)(一个同源的小BUG?a common source of subtle bugs)。

 
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="PropertyEvaluation">
<head>
<meta charset="UTF-8">
<title>PropertyEvaluation</title>
<style type="text/css">
.ng-cloak {
display: none;
}
</style>
</head>
<body>
<div ng-controller="MyCtrl">
Name: <input ng-model="name" type="text"/>
<button ng-click="greet()">Greet</button>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
var app = angular.module("PropertyEvaluation", []);
app.controller("MyCtrl", function ($scope,$window) {
$scope.name = "Kitty";
$scope.greet = function() {
$window.alert("Hello " + $scope.name);
};
});
</script>
</body>
</html>
 

三、Forgiving(宽容,容错?)

  表达式求值对undefined和null是宽容的。在javascript中,当a不是object的时候,对a.b.c求值,那么将会抛出一个异常。有时候这对于通用语言来说是合理的,而表达式求值主要用于数据绑定,一般形式如下:

{{a.b.c}}

  如果a不存在,没有任何显示似乎比抛出异常更加合理(除非我们等待服务端响应,不一会儿就会被定义)。如果表达式求值时不够宽容,那么我们如此混乱地写绑定代码:

{{((a||{}).b||{}).c}}    //这……

  相似地,引用一个函数a.b.c()时,如果它是undefined或者null,那么简单地返回undefined。

四、没有控制流程语句(No Control Flow Statements)

  我们不可以在表达式中写流程控制语句。背后的原因是,angular的核心体系是应用的逻辑应当在controller(的scope)里面,而不是在view里面。如果我们需要在视图表达式中加入条件分支、循环或者抛出异常的话,可以委托javascript方法去代替(可以调用scope中的方法)。

五、过滤器(Filters)

  当我们向用户呈现数据时,我们可能需要将数据从原始格式转换为友好(可读性强)的格式。例如,我们有一个数据对象需要在显示给用户之前根据地域进行格式化。我们可以将表达式传递给一连串的过滤器,如:

name | uppercase

  这表达式求值器可简单地传递name的值到uppercase过滤器中。

  链式过滤器使用这种语法:

value | filter1 | filter2

  我们也可以传送用冒号分割的参数到filter中,例如,以两位小数的格式显示123:

123 | number:2

六、前缀”$”

  我们可能会感到奇怪,前缀”$”的意义是什么?它是angular为了使本身的API名称能够区别于其他的API而使用的一个简单的前缀(防止冲突)。如果angular不使用$,那么对a.length()求值将返回undefined。因为a和angular本身都没有定义这个属性。

  考虑到angular将来的版本可能会选择增加length这个方法,这将令这个表达式的行为发生改变。更糟糕的是,我们开发者可能会创建一个length属性,那么将与angular发生冲突。这个问题存在因为angular通过增加方法扩展了当前存在的对象。通过加入前缀”$”,angular保留了特定的namespace,所以angular的开发者与使用angular的开发者都可以和谐共处。

  1. AngularJs学习笔记--bootstrap
  2. AngularJs学习笔记--html compiler
  3. AngularJs学习笔记--concepts
  4. AngularJs学习笔记--directive
  5. AngularJs学习笔记--expression
  6. AngularJs学习笔记--Forms
  7. AngularJs学习笔记--I18n/L10n
  8. AngularJs学习笔记--IE Compatibility
  9. AngularJs学习笔记--Modules
  10. AngularJs学习笔记--Scope
  11. AngularJs学习笔记--Dependency Injection
  12. AngularJs学习笔记--Understanding the Model Component
  13. AngularJs学习笔记--Understanding the Controller Component
  14. AngularJs学习笔记--E2E Testing
  15. AngularJs学习笔记--Understanding Angular Templates
  16. AngularJs学习笔记--Using $location
  17. AngularJs学习笔记--Creating Services
  18. AngularJs学习笔记--Injecting Services Into Controllers
  19. AngularJs学习笔记--Managing Service Dependencies
  20. AngularJs学习笔记--unit-testing

AngularJs学习笔记--expression的更多相关文章

  1. AngularJs学习笔记--Forms

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/forms 控件(input.select.textarea)是用户输入数据的一种方式.Form(表单) ...

  2. AngularJs学习笔记--directive

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/directive Directive是教HTML玩一些新把戏的途径.在DOM编译期间,directiv ...

  3. AngularJs学习笔记--Guide教程系列文章索引

    在很久很久以前,一位前辈向我推荐AngularJs.但当时我没有好好学习,仅仅是讲文档浏览了一次.后来觉醒了……于是下定决心好好理解这系列的文档,并意译出来(英文水平不足……不能说是翻译,有些实在是看 ...

  4. AngularJs学习笔记--bootstrap

    AngularJs学习笔记系列第一篇,希望我可以坚持写下去.本文内容主要来自 http://docs.angularjs.org/guide/ 文档的内容,但也加入些许自己的理解与尝试结果. 一.总括 ...

  5. AngularJs学习笔记--html compiler

    原文再续,书接上回...依旧参考http://code.angularjs.org/1.0.2/docs/guide/compiler 一.总括 Angular的HTML compiler允许开发者自 ...

  6. AngularJs学习笔记--concepts(概念)

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/concepts 继续.. 一.总括 本文主要是angular组件(components)的概览,并说明 ...

  7. AngularJs学习笔记--Using $location

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/dev_guide.services.$location 一.What does it do? $loc ...

  8. AngularJs学习笔记--unit-testing

    原版地址:http://docs.angularjs.org/guide/dev_guide.unit-testing javascript是一门动态类型语言,这给她带来了很强的表现能力,但同时也使编 ...

  9. AngularJs学习笔记--Managing Service Dependencies

    原版地址:http://docs.angularjs.org/guide/dev_guide.services.managing_dependencies angular允许service将其他ser ...

随机推荐

  1. Python之mongodb操作

    1.安装驱动pymongo 输入命令:pip install pymongo 2.直接使用驱动 #encoding=utf-8 from pymongo import MongoClient clie ...

  2. python 核心编程第二版 课后习题 第11章

    11-3 函数.在这个练习中,我们将实现 max()和 min()内建函数. (a) 写分别带两个元素返回一个较大和较小元素,简单的 max2()核 min2()函数.他们应该可以用任意的 pytho ...

  3. unp.h

    unp.h #ifndef _UNP_H_ #define _UNP_H_ #include <unistd.h> #include <stdio.h> #include &l ...

  4. 金融系列14《QPBOC交易流程》

    中国银行金融IC卡qPBOC交易时间(不含终端处理时间)要求:IC卡私钥长度1024位,交易时间 <= 500ms, 1152 <=600 ATR=3B8D800100814D220886 ...

  5. mysql索引合并:一条sql可以使用多个索引

    前言 mysql的索引合并并不是什么新特性.早在mysql5.0版本就已经实现.之所以还写这篇博文,是因为好多人还一直保留着一条sql语句只能使用一个索引的错误观念.本文会通过一些示例来说明如何使用索 ...

  6. JVM学习总结二——垃圾回收算法

    昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...

  7. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  8. unity2d之2d帧动画创建

    在2d游戏中帧动画的应用是非常广泛的,那么如何在unity中创建一个帧动画,主要是下面几个步骤. 原文地址  :http://blog.csdn.net/dingkun520wy/article/de ...

  9. WIN7笔记本利用命令AP热点

    第一步:以管理员身份运行命令提示符:开始”---搜索栏输入“cmd----右键以“管理员身份运行”自己随便命名,第二步:运行命令:netsh wlan set hostednetwork mode=a ...

  10. 微软职位内部推荐-Software Engineer II-SDP

    微软近期Open的职位: Position: SDE II The R&D of Shared Data Platform at Application and Services Group ...