AngularJs expression详解及简单示例


Posted in Javascript onSeptember 01, 2016

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

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

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

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

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

  1. 属性求值:所有属性的求值是对于scope的,而javascript是对于window对象的。
  2. 宽容(forgiving):表达式求值,对于undefined和null,angular是宽容的,但Javascript会产生NullPointerExceptions(-_-!!!!怎么我没见过)。
  3. 没有流程控制语句:在angular表达式里,我们不能做以下任何的事:条件分支、循环、抛出异常。
  4. 过滤器(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的开发者都可以和谐共处。

Javascript 相关文章推荐
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
Jul 31 Javascript
JQuery做的一个简单的点灯游戏分享
Jul 16 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
Mar 11 Javascript
基于Bootstrap3表格插件和分页插件实例详解
May 17 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
May 25 Javascript
jquery根据一个值来选中select下的option实例代码
Aug 29 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
May 07 Javascript
vue项目常用组件和框架结构介绍
Dec 24 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
Aug 10 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
Aug 22 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
Jul 19 Javascript
Openlayers实现距离面积测量
Sep 28 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
Sep 01 #Javascript
vue.js入门教程之基础语法小结
Sep 01 #Javascript
AngularJs directive详解及示例代码
Sep 01 #Javascript
AngularJs concepts详解及示例代码
Sep 01 #Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
Sep 01 #Javascript
AngularJs html compiler详解及示例代码
Sep 01 #Javascript
AngularJs bootstrap搭载前台框架——js控制部分
Sep 01 #Javascript
You might like
PHP获取网站域名和地址的代码
2008/08/17 PHP
DOM XPATH获取img src值的query
2013/09/23 PHP
php反射应用示例
2014/02/25 PHP
php基于str_pad实现卡号不足位数自动补0的方法
2014/11/12 PHP
PHP使用HTML5 FormData对象提交表单操作示例
2019/07/02 PHP
asp批量修改记录的代码
2008/06/25 Javascript
JS禁用浏览器退格键实现思路及代码
2013/10/29 Javascript
jquery选择符快速提取web表单数据示例
2014/03/27 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
JavaScript中this的9种应用场景及三种复合应用场景
2015/09/12 Javascript
JS基于面向对象实现的拖拽库实例
2015/09/24 Javascript
JavaScript禁止复制与粘贴的实现代码
2016/05/16 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
2016/06/26 Javascript
JavaScript实现弹窗效果代码分析
2017/03/09 Javascript
angular2+nodejs实现图片上传功能
2017/03/27 NodeJs
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
Python获取脚本所在目录的正确方法
2014/04/15 Python
用Python编写一个每天都在系统下新建一个文件夹的脚本
2015/05/04 Python
Python列出一个文件夹及其子目录的所有文件
2016/06/30 Python
python使用PyCharm进行远程开发和调试
2017/11/02 Python
Python 判断 有向图 是否有环的实例讲解
2018/02/01 Python
python 实现将文件或文件夹用相对路径打包为 tar.gz 文件的方法
2019/06/10 Python
Python适配器模式代码实现解析
2019/08/02 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
2020/02/05 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
python如何调用百度识图api
2020/09/29 Python
python爬虫快速响应服务器的做法
2020/11/24 Python
Python解析m3u8拼接下载mp4视频文件的示例代码
2021/03/03 Python
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
《中彩那天》教学反思
2014/02/22 职场文书
片区教研活动总结
2014/07/02 职场文书
离婚协议书该怎么写
2014/10/04 职场文书
家属慰问信
2015/02/14 职场文书
golang中的空slice案例
2021/04/27 Golang