---恢复内容开始---

表达式是类似Javascript的代码片段,通常在绑定中用到,写在双大括号中如{{表达式}}。表达式是用$parse方法来处理的。

下面是一些合法的AngularJS表达式

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

AngularJS表达式 与Javascript表达式的比较

你可能会认为AngularJS视图中的表达式就是Javascript表达式,这种认识不完全对,因为AngularJS不会用Javascript的eval()函数去执行表达式。 不过除了以下几个需要区别的地方以外,你可以把AngularJS表达式看成是Javascript表达式: formatDate

  • 属性表达式:属性表达式是对应于当前的作用域的,不像Javascript对应的是全局window对象。
  • 允许未定义值:执行表达式时,AngularJS能够允许undefined或者null,不像Javascript会抛出一个异常。
  • 没有控制结构: 你不能在AngularJS表达式中使用“条件判断”、“循环”、“抛出异常”等控制结构。
  • 过滤器(类似unix中的管道操作符): 你可以通过过滤器链来传递表达式的结果。例如将日期对象转变成指定的阅读友好的格式。

如果你想要在表达式中使用标准的Javascript,那么你应该把它写成一个控制器的方法,然后在表达式中调用这个方法。如果你想在Javascript中执行AngularJS表达式,你可以使用$eval()方法。

例子

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
</head>
<body>
1+2={{1+2}}
</body>
</html>

端对端测试:

it('should calculate expression in binding', function() {
expect(binding('1+2')).toEqual('3');
});

你可以用下面的例子试试别的表达式:

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<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>
</body>
</html>

script.js:

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);
};
}

端对端测试:

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"]);
});

属性表达式

属性表达式计算是发生在作用域中的。Javascript默认是以window为作用域的。AngularJS要使用window作用域的话得用$window来指向全局window对象。 比如说,你使用window中定义的alert()方法,在AngularJS表达式中必须写成$window.alert()才行。这是为了防止意外进入全局作用域(各种bug的来源)而设计的。

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div class="example2" ng-controller="Cntl1">
Name: <input ng-model="name" type="text"/>
<button ng-click="greet()">Greet</button>
</div>
</body>
</html>

script.js:

function Cntl1($window, $scope){
$scope.name = 'World'; $scope.greet = function() {
($window.mockWindow || $window).alert('Hello ' + $scope.name);
}
}

端对端测试:

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');
});

允许未定义值

表达式在执行时是可以允许undifinednull的。 在Javascript中,计算a.b.c会抛出一个异常,如果这不是一个对象的话。这对大部分的语言来说是有意义的,但是如果大多数时候表达式是用来作数绑定,像下面这种形式:

{{a.b.c}}

那么表达式返回一个空值会比触发异常更有意义。因为通常我们是在等待服务器的响应,并且变量马上就会被定义和赋值。如果表达式不能容忍未定义的值,那么我们绑定的代码就不得不写成形如:

{{((a||{}).b||{}).c}}

执行未定义的函数a.b.c()也会返回undefined,不会触发异常。

没有流程控制结构

你不能在表达式中使用控制结构。这样设计得原因在于AngularJS的设计理念之一就是逻辑代码都应该在控制器里。如果你需要使用条件、循环、或者处理异常,你就应该写在控制器的方法里。

过滤器

当将数据呈献给用户时,你很可能需要将数据转换为阅读友好的格式。比方说,你可能需要在显示之前将一个日期对象转换为用户本地的时间格式。你可以用链式的过滤器来传递表达式,像下面这样:

name | uppercase

这个表达式会将name的值传递给uppercase这个过滤器。

链式过滤器使用的是下面这样的语法:

value | filter1 | filter2

你也可以通过冒号来给过滤器传递参数,比如,将123显示成带有两位小数的形式:

123 | number:2

$符号

你可能会好奇,这个$的前缀有什么用?其实这只是一个标记AngularJS专有属性方法的符号,用来表示区别于其他用户自定义函数的符号。如果AngularJS不用$,那么执行a.length()会返回undeifined,因为a和angular都没有这样一个属性。

但是考虑到我们以后可能会增加一个length的方法(这会改变表达式的行为),同时你也想要自己增加一个length方法的话,那就会产生冲突。 这种冲突可能出现都是因为,AngularJS的设计是在已有的对象上添加行为。使用$做前缀的话,就能使得开发者的代码和AngularJS和谐共处 了。

---恢复内容结束---

表达式是类似Javascript的代码片段,通常在绑定中用到,写在双大括号中如{{表达式}}。表达式是用$parse方法来处理的。

下面是一些合法的AngularJS表达式

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

AngularJS表达式 与Javascript表达式的比较

你可能会认为AngularJS视图中的表达式就是Javascript表达式,这种认识不完全对,因为AngularJS不会用Javascript的eval()函数去执行表达式。 不过除了以下几个需要区别的地方以外,你可以把AngularJS表达式看成是Javascript表达式: formatDate

  • 属性表达式:属性表达式是对应于当前的作用域的,不像Javascript对应的是全局window对象。
  • 允许未定义值:执行表达式时,AngularJS能够允许undefined或者null,不像Javascript会抛出一个异常。
  • 没有控制结构: 你不能在AngularJS表达式中使用“条件判断”、“循环”、“抛出异常”等控制结构。
  • 过滤器(类似unix中的管道操作符): 你可以通过过滤器链来传递表达式的结果。例如将日期对象转变成指定的阅读友好的格式。

如果你想要在表达式中使用标准的Javascript,那么你应该把它写成一个控制器的方法,然后在表达式中调用这个方法。如果你想在Javascript中执行AngularJS表达式,你可以使用$eval()方法。

例子

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
</head>
<body>
1+2={{1+2}}
</body>
</html>

端对端测试:

it('should calculate expression in binding', function() {
expect(binding('1+2')).toEqual('3');
});

你可以用下面的例子试试别的表达式:

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<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>
</body>
</html>

script.js:

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);
};
}

端对端测试:

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"]);
});

属性表达式

属性表达式计算是发生在作用域中的。Javascript默认是以window为作用域的。AngularJS要使用window作用域的话得用$window来指向全局window对象。 比如说,你使用window中定义的alert()方法,在AngularJS表达式中必须写成$window.alert()才行。这是为了防止意外进入全局作用域(各种bug的来源)而设计的。

index.html:

<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div class="example2" ng-controller="Cntl1">
Name: <input ng-model="name" type="text"/>
<button ng-click="greet()">Greet</button>
</div>
</body>
</html>

script.js:

function Cntl1($window, $scope){
$scope.name = 'World'; $scope.greet = function() {
($window.mockWindow || $window).alert('Hello ' + $scope.name);
}
}

端对端测试:

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');
});

允许未定义值

表达式在执行时是可以允许undifinednull的。 在Javascript中,计算a.b.c会抛出一个异常,如果这不是一个对象的话。这对大部分的语言来说是有意义的,但是如果大多数时候表达式是用来作数绑定,像下面这种形式:

{{a.b.c}}

那么表达式返回一个空值会比触发异常更有意义。因为通常我们是在等待服务器的响应,并且变量马上就会被定义和赋值。如果表达式不能容忍未定义的值,那么我们绑定的代码就不得不写成形如:

{{((a||{}).b||{}).c}}

执行未定义的函数a.b.c()也会返回undefined,不会触发异常。

没有流程控制结构

你不能在表达式中使用控制结构。这样设计得原因在于AngularJS的设计理念之一就是逻辑代码都应该在控制器里。如果你需要使用条件、循环、或者处理异常,你就应该写在控制器的方法里。

过滤器

当将数据呈献给用户时,你很可能需要将数据转换为阅读友好的格式。比方说,你可能需要在显示之前将一个日期对象转换为用户本地的时间格式。你可以用链式的过滤器来传递表达式,像下面这样:

name | uppercase

这个表达式会将name的值传递给uppercase这个过滤器。

链式过滤器使用的是下面这样的语法:

value | filter1 | filter2

你也可以通过冒号来给过滤器传递参数,比如,将123显示成带有两位小数的形式:

123 | number:2

$符号

你可能会好奇,这个$的前缀有什么用?其实这只是一个标记AngularJS专有属性方法的符号,用来表示区别于其他用户自定义函数的符号。如果AngularJS不用$,那么执行a.length()会返回undeifined,因为a和angular都没有这样一个属性。

但是考虑到我们以后可能会增加一个length的方法(这会改变表达式的行为),同时你也想要自己增加一个length方法的话,那就会产生冲突。 这种冲突可能出现都是因为,AngularJS的设计是在已有的对象上添加行为。使用$做前缀的话,就能使得开发者的代码和AngularJS和谐共处 了。

AngularJS开发指南:表达式的更多相关文章

  1. AngularJS开发指南16:AngularJS构建大型Web应用详解

    AngularJS是由Google创建的一种JS框架,使用它可以扩展应用程序中的HTML功能,从而在web应用程序中使用HTML声明动态内容.在该团队工作的软件工程师Brian Ford近日撰写了一篇 ...

  2. AngularJS开发指南5:AngularJS表达式详解

    AngularJS表达式类似Javascript的代码片段,通常在数据绑定中用到,写在双大括号中,如:{{表达式}}.表达式是用$parse方法来处理的. 下面是一些合法的AngularJS表达式 1 ...

  3. AngularJS开发指南12:AngularJS的模板,CSS,数据绑定详解

    模板 AngularJS模板是一种声明式的规则.它包含了模型和控制器的信息,最后会被渲染成用户在浏览器中看到的视图.它是静态的DOM,包含HTML,CSS和AngularJS指定的元素和属性.Angu ...

  4. AngularJS开发指南4:指令的详解

    指令是我们用来扩展浏览器能力的技术之一.在DOM编译期间,和HTML元素关联着的指令会被检测到,并且被执行.这使得指令可以为DOM指定行为,或者改变它. AngularJS有一套完整的.可扩展的.用来 ...

  5. AngularJS开发指南1:AngularJS简介

    什么是 AngularJS? AngularJS 是一个为动态WEB应用设计的结构框架.它能让你使用HTML作为模板语言,通过扩展HTML的语法,让你能更清楚.简洁地构建你的应用组件.它的创新点在于, ...

  6. AngularJS开发指南11:AngularJS的model,controller,view详解

    model model这个词在AngularJS中,既可以表示一个(比如,一个叫做phones的model,它的值是一个包含多个phone的数组)对象,也可以表示应用中的整个数据模型,这取决于我们所讨 ...

  7. AngularJS开发指南13:AngularJS的过滤器详解

    AngularJS过滤器是用来格式化输出数据的.除了格式化数据,过滤器还能修改DOM.这使得过滤器通常用来做些如“适时的给输出加入CSS样式”等工作. 比如,你可能有些数据在输出之前需要根据进行本地化 ...

  8. AngularJS开发指南9:AngularJS作用域的详解

    AngularJS作用域是一个指向应用模型的对象.它是表达式的执行环境.作用域有层次结构,这个层次和相应的DOM几乎是一样的.作用域能监控表达式和传递事件. 作用域的特点 作用域提供APIs($wat ...

  9. AngularJS开发指南8:AngularJS模块的详解

    在讲angularjs的模块之前,我们先介绍一下angular的一些知识点: AngularJS是纯客户端技术,完全用Javascript编写的.它使用的是网页开发的常规技术(HTML,CSS,Jav ...

随机推荐

  1. L2-031 深入虎穴(BFS)

    著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报.已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门.每一扇门背后或者是一个房间,或者又有很多条路,同样是每条 ...

  2. golang基础--类型与变量

    基础知识--类型与变量 基本类型 布尔型:bool 长度: 1字节 取值范围: false, true 注意事项: 不可以使用数字代表,不像 python中可是使用 1和0表示 整型: int/uin ...

  3. PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数

    题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里 ...

  4. 《Linux内核分析》第三周:Linux系统启动过程

    杨舒雯 原创作品转载请注明出处 Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验--使用gdb跟踪调试内 ...

  5. 个人作业3——个人总结AlPha阶段

    一.Alpha版本的总结 1.感受 Alpha版本已经结束了,回顾整个过程,我最大的遗憾就是项目完成得不是很理想,同时觉得自己做得不够多.不够好. 2.我做了哪些工作 数据库的连接,部分团队博客:部分 ...

  6. webpack 学习笔记 (一)

    webpack 作为当下前端前沿最受欢迎的打包工具,作为一个前端开发人员是很有必要去了解下它的. 题外话: npm i -D 是 npm install  --save-dev的简写,是安装模块并保存 ...

  7. C++学习记录(留坑)

    #include <iostream> #include <ctime> #include <fstream> ///文件打开有o.i权限 #include < ...

  8. Linux命令(四)删除文件 rm

    用户可以使用 rm 命令删除不需要的文件. rm 可以删除文件或目录,并且支持通配符. 如果目录中存在其它文件则会递归删除. 删除软链接只是删除链接,对应的文件或目录不会被删除. 软链接类似于 win ...

  9. Docker(四)-Dcoker镜像

    Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地, Docker 会从镜像仓库下载(默认是Docker Hub公共注册服务器中的仓库). Docker Hub:https://hub ...

  10. IntelliJ IDEA中文乱码问题

    转自  https://blog.csdn.net/m0_37893932/article/details/78280663 1 file->settings->appearence里面有 ...