2. 表达式
AngularJS表达式主要用于在HTML页面上生成输出,AngularJS表达式与普JavaScript表达式类似,同样支持变量以及各种运算符。只要将AngularJS的表达式放在{{}}中即可。
2.1 简单表达式
AngularJS的简单表达式既可由直接量(包括数值、字符串、boolean值等),也可由变量组成。下面先看几个包含直接量的表达式。代码如下:
<body ng-app>
{{2 * 5 + 200/3}}</p>
{{'hello' + 'zdk.com' }}</p>
{{'Hello' + 4 + 3 }}</p>
{{'Hello' + (4 + 3) }}</p>
</body>
上面4个表达式都是由直接量组成,这些直接量参与了数值、字符串的运算,也参与了数字和字符串的混合运算,AngularJS完全可以正常处理这些表达式。一般来说,JavaScript可以处理的表达式,AngularJS都可以正常处理。此外,AngularJS还提供了ng-bind指令,该指令用于将表达式的值绑定到HTML元素(如<span…/>、<div…/>、<p…/>等)的innerHTML,这样这些 HTML 元素也用于显示 AngularJS表达式的值。例如也可将上面代码改为如下形式(代码同上)。
<body ng-app>
<p ng-bind="2 * 5 + 200/3"></p>
<p ng-bind="'hello' + 'zdk.com'"></p>
<p ng-bind="'Hello' + 4 + 3 "></p>
<p ng-bind="'Hello' + (4 + 3)"></p>
</body>
正如前面提到的,AngularJS表达式也可以处理变量,例如如下代码:
<body ng-app ng-init="domain='zdk.com';name='ZDK小白学习网'">
{{'我们的域名是:' + domain}}</p>
{{'我们的名称是:' + name}}</p>
<div ng-init="num=5">
num的平方为: {{num * num}}
</div>
num的立方为: {{num * num * num}}
</body>
在这段代码中又用到一个AngularJS的指令:ng-init,该指令用于声明变量,该指令的属性值可声明一个或多个变量,多个变量直接用分号隔开即可。
提示:
ng-init指令的属性值就是一条或多条JavaScript定义变量的语句。也可将上面代码改为使用ng-bind来显示表达式的值,代码如下:
<body ng-app ng-init="domain='zdk.com';name='ZDK小白学习网'">
<p ng-bind="'我们的域名是:' + domain"></p>
<p ng-bind="'我们的名称是:' + name"></p>
<div ng-init="num=5">
num的平方为: <span ng-bind="num * num"></span>
</div>
num的立方为: <span ng-bind="num * num * num"></span>
</body>
2.2 复合对象表达式
AngularJS 表达式也支持使用对象、数组等复合类型。例如下面代码在AngularJS表达式中使用对象。
<body ng-app ng-init="zdk={domain:'zdk.com',name:'ZDK小白学习网'}">
{{'我们的域名是:' + zdk.domain}}</p>
{{'我们的名称是:' + zdk.name}}</p>
</body>
第一行代码使用ng-init指令初始化了一个zdk对象,该对象包含name和domain两个属性。接下来程序在AngularJS表达式中访问fkit的name和domain属性,如第二行粗体字代码所示。同样也可使用ng-bind指令来执行输出:
<body ng-app ng-init="zdk={domain:'zdk.com',name:'ZDK小白学习网'}">
<p ng-bind="'我们的域名是:' + zdk.domain"></p>
<p ng-bind="'我们的名称是:' + zdk.name"></p>
</body>
下面的代码示范了在AngularJS表达式中使用数组。
<body ng-app ng-init="users=[{name:'aaa',age:11},{name:'bbb',age:12},{name:'ccc',age:13}]">
第一个用户的名字是:{{users[0].name}},年龄是:{{users[0].age}}</p>
第二个用户的名字是:{{users[1].name}},年龄是:{{users[1].age}}</p>
第三个用户的名字是:{{users[2].name}},年龄是:{{users[2].age}}</p>
</body>
第一行代码使用ng-init初始化了一个users数组,每个数组元素都是对象。接下来程序在AngularJS表达式中通过下标来访问users数组的不同元素。同样也可使用ng-bind指令来执行输出(代码同上)。
<body ng-app ng-init="users=[{name:'aaa',age:11},{name:'bbb',age:12},{name:'ccc',age:13}]">
第一个用户的名字是:<span ng-bind="users[0].name"></span>
,年龄是:<span ng-bind="users[0].age"></span><br>
第二个用户的名字是:<span ng-bind="users[1].name"></span>
,年龄是:<span ng-bind="users[1].age"></span><br>
第三个用户的名字是:<span ng-bind="users[2].name"></span>
,年龄是:<span ng-bind="users[2].age"></span>
</body>
2.3 AngularJS表达式的容错性
AngularJS表达式被设计得非常强壮,它可以自动处理空指针异常的问题。例如如下代码:
<body ng-app>
第一个用户的名字是:{{user.pig.name}}</p>
打招呼:{{'hello' + user.name}}</p>
</body>
注意看粗体字代码,这行代码访问了user对象的pig属性的name属性,但当前AngularJS应用中根本就没有user对象,如果这里的表达式是一个普通的JavaScript表达式,则执行这行代码必然引发错误,但这是一个AngularJS表达式,因此不会引起错误,这就是AngularJS表达式的容错性:AngularJS 表达式会自动判断某个变量是否存在,如果该变量不存在,则 AngularJS将会把对该变量的后续处理都解析为空。
因此上面代码页面的执行效果如图所示:
由此可见,AngularJS表达式可以正常处理null和 undefined 值,而不会抛出任何异常。如果用代码来表示,如下表达式:
{{a.b.c}} 等同于 ((a || {}).b || {}).c
2.4 AngularJS表达式与JavaScript表达式
由前所述,AngularJS 表达式和 JavaScript 表达式虽然有很多相似之处,但也存在不小的差别。从容错性方面来看,AngularJS表达式比JavaScript表达式的功能更强一些。总结起来,AngularJS表达式与JavaScript表达式存在如下差异:
➢ JavaScript表达式不能直接出现在HTML中,而AngularJS表达式可以直接写在HTML中,只要放在{{}}中即可。
➢ AngularJS 表达式具有更好的容错性,AngularJS表达式可以自动处理表达式中出现的undefined或null值,而不会出现NullPointerExceptions。
➢ 与JavaScript表达式不同的是,AngularJS表达式不支持分支、循环及异常处理。
➢ AngularJS表达式支持大量功能丰富的过滤器。
提示:
关于AngularJS过滤器,后面文章会有详细介绍。
➢ AngularJS表达式中的变量是基于 s c o p e 的 , 而 J a v a S c r i p t 表 达 式 中 的 变 量 通 常 是 全 局 变 量 , 也 即 基 于 w i n d o w 对 象 。 提 示 : 关 于 scope 的,而JavaScript表达式中的变量通常是全局变量,也即基于window对象。提示:关于 scope的,而JavaScript表达式中的变量通常是全局变量,也即基于window对象。提示:关于scope 作用域,本章后面也会有详细介绍。如果 AngularJS需要访问JavaScript的变量或表达式,则可通过$window服务访问,后面文章也会对此有详细介绍。