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 相关文章推荐
Javascript的一种模块模式
Mar 22 Javascript
javascript FormatNumber函数实现方法
Dec 30 Javascript
jquery 日期分离成年月日的代码
May 14 Javascript
简略说明Javascript中的= =(等于)与= = =(全等于)区别
Apr 16 Javascript
JS实现动态生成表格并提交表格数据向后端
Nov 25 Javascript
Vue.js创建Calendar日历效果
Nov 03 Javascript
用JavaScript和jQuery实现瀑布流
Mar 19 Javascript
微信小程序实现顶部普通选项卡效果(非swiper)
Jun 19 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
Apr 20 jQuery
一文快速了解JQuery中的AJAX
May 31 jQuery
jquery选择器和属性对象的操作实例分析
Jan 10 jQuery
vue实现表单未编辑或未保存离开弹窗提示功能
Apr 08 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
ThinkPHP有变量的where条件分页实例
2014/11/03 PHP
php常用字符串处理函数实例分析
2014/11/22 PHP
微信公众平台实现获取用户OpenID的方法
2015/04/15 PHP
php生成动态验证码gif图片
2015/10/19 PHP
js获取变量
2006/08/24 Javascript
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
基于jquery的网页SELECT下拉框美化代码
2010/10/28 Javascript
JS使用post提交的两种方式
2015/12/03 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
2017/02/27 Javascript
浅谈事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流
2017/07/22 jQuery
JS实现静态页面搜索并高亮显示功能完整示例
2017/09/19 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
2019 年编写现代 JavaScript 代码的5个小技巧(小结)
2019/01/15 Javascript
JS数组扁平化、去重、排序操作实例详解
2020/02/24 Javascript
JavaScript实现筛选数组
2021/03/02 Javascript
[00:08]DOTA2勇士令状等级奖励“天外飞星”
2019/05/24 DOTA
Python实现的一个找零钱的小程序代码分享
2014/08/25 Python
Python实现抓取百度搜索结果页的网站标题信息
2015/01/22 Python
python 字符串只保留汉字的方法
2018/11/16 Python
matplotlib实现显示伪彩色图像及色度条
2019/12/07 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
Keras自定义IOU方式
2020/06/10 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
在校学生职业规划范文
2014/01/08 职场文书
运动会入场词100字
2014/02/06 职场文书
教师党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
党的群众路线教育实践活动个人自我剖析材料
2014/10/07 职场文书
付款承诺函范文
2015/01/21 职场文书
酒店员工手册范本
2015/05/14 职场文书
合作协议书格式范本
2016/03/21 职场文书
Redis数据结构之链表与字典的使用
2021/05/11 Redis
再也不用花钱买漫画!Python爬取某漫画的脚本及源码
2021/06/09 Python
python中pandas对多列进行分组统计的实现
2021/06/18 Python
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python