转载请写明来源地址:http://www.jb51.cc/article/p-fbbhsaxb-bph.html

angular表达式

angular表达式是一些类似javascript的代码片段,主要用在插补绑定,例如<span title="{{ attrBinding }}">{{ textBinding }}</span>,或者直接用于angular指令的属性值,例如ng-click="functionExpression()"

有效表达式示例如下:

  • 1+2
  • a+b
  • user.name
  • items[index]

angular表达式 VS javascript表达式

angular表达式和javascript表达式很相似,但也有些不同之处,如下:

  • Context:javascript表达式的Context可以是整个window,而angular的Context只是一个scope对象范围内。
  • Forgiving:javascript中,如果对undefined的属性求值会产生ReferenceError和TypeError错误,而在angular中,表达式的求值会对undefined和null非常宽容。
  • Filters:可以在展示数据之前先用filters对表达式进行数据格式化。
  • 不能写控制流语句:不能在angular表达式写控制流语句:条件,循环,异常。
  • 不能做函数定义:不能在angular表达式定义函数,即使在ng-init指令中。
  • 不能用在正则表达式:不能在angular表达式创建正则表达式。
  • 不能用new创建对象:不能在angular表达式用new操作符创建对象。
  • 不能使用位,逗号,void操作符:不能再angular表达式使用位,逗号,void操作符。

示例

这个示例可以计算不同的angular表达式:

<!DOCTYPE html> <html> <head> <Meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script> angular.module('expressionExample',[]) .controller('ExampleController',['$scope',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 ng-app="expressionExample"> <div ng-controller="ExampleController" 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 track by $index"> [ <a href="" ng-click="removeExp($index)">X</a> ] <code>{{expr}}</code> => <span ng-bind="$parent.$eval(expr)"></span> </li> </ul> </div> </body> </html>

Context

angular不能用javascript的eval()方法对表达式进行求值,而且用angular的$parse服务来处理这些表达式。
angular表达式不能直接访问全局变量window,document,location。这种限制是angular有意这样规定的,防止访问常见bug的来源。
你可以在控制器的函数中去使用$window$location服务,然后从表达式中调用,这些服务也可以访问全局变量。
可以用this标识符访问上下文对象,也可以用$locals标识符访问locals的对象

<!DOCTYPE html>
<html>
<head>
    <Meta charset="uft-8"/>
    <title></title>
</head>
<script src="script/angular.min.js"></script>
<script> angular.module('expressionExample',['$window','$scope',function($window,$scope) { $scope.name = 'World'; $scope.greet = function() { $window.alert('Hello ' + $scope.name); }; }]); </script>
<body ng-app="expressionExample">
<div class="example2" ng-controller="ExampleController">
    Name: <input ng-model="name" type="text"/>
    <button ng-click="greet()">Greet</button>
    <button ng-click="alert('Should not see me')">Won't greet</button>
</div>

</body>
</html>

Forgiving

表达式求值对undefined和null是宽容的。在javascript中对a.b.c求值时,如果a不是一个对象,就会抛异常。作为一个通用语言,表达式求值主要用于数据绑定,通常是这样:

{{a.b.c}}

a如果是undefined(可能我们在等待服务器的返回,它马上就会变成defined),这时候什么也不显示通常要比抛出一个异常明智的多。如果表达式求值不能宽容,那么我们需要写杂乱的绑定代码,如下:

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

同样,在undefined或者null的情况下,调用a的函数a.b.c()也只是简单的返回undefined

不能写控制流语句

除了三元运算符,你不能在angular表达式写一个控制流语句。这和angular的核心思想有关:应用的逻辑应该在控制器中,而不是视图中。如果你确实需要在angular表达式写一个条件,循环,或者异常,委托给javascript方法。

不能做函数定义和正则表达式

你不能在angular表达式定义函数或者创建正则表达式,这样可以避免模板中有复杂的模型转换逻辑。这些逻辑可以放在控制器中或者一个专门的过滤器中,控制器和过滤器还方面进行测试。

$event

ngClickngFocus这样的指令会讲\$event对象暴露给表达式的scope,这个对象是个jQuery事件对象或者说一个jqLite对象。

<!DOCTYPE html> <html> <head> <Meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script> angular.module('eventExampleApp',[]). controller('EventController',function($scope) { /* * 暴露事件对象给scope */ $scope.clickMe = function(clickEvent) { $scope.clickEvent = simpleKeys(clickEvent); console.log(clickEvent); }; /* * 返回一个非对象键的对象拷贝 * 防止循环引用 */ function simpleKeys(original) { return Object.keys(original).reduce(function(obj,key) { obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key]; return obj; },{}); } }]); </script> <body ng-app="eventExampleApp"> <div ng-controller="EventController"> <button ng-click="clickMe($event)">Event</button> <p><code>$event</code>: <pre> {{$event | json}}</pre></p> <p><code>clickEvent</code>: <pre>{{clickEvent | json}}</pre></p> </div> </body> </html>

注意在上面的例子中,我们可以传递$eventclickMe,但是不能显示{{\$event}},因为$event超出了绑定的scope。

一次性绑定

一次性表达式以::开头,当它们稳定后就会停止重新计算,这里说的稳定是指第一次digest之后表达式的值不是undefined的情况下。

<!DOCTYPE html> <html> <head> <Meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script> angular.module('oneTimeBidingExampleApp',function($scope) { var counter = 0; var names = ['Igor','Misko','Chirayu','Lucas']; /* * expose the event object to the scope */ $scope.clickMe = function(clickEvent) { $scope.name = names[counter % names.length]; counter++; }; }]); </script> <body ng-app="oneTimeBidingExampleApp"> <div ng-controller="EventController"> <button ng-click="clickMe($event)">Click Me</button> <p id="one-time-binding-example">One time binding: {{::name}}</p> <p id="normal-binding-example">normal binding: {{name}}</p> </div> </body> </html>

使用一次性绑定的原因

一次性绑定的主要目的是,提供了创建绑定的方法,一旦绑定被稳定化,相应的资源就可以被注销和释放。减少需要观察的表达式数量,使得digest循环更快速,在相同时间内更多的信息可以展示出来。

价值稳定算法

只要该值不是undefined,一次性绑定表达式只会保留digest结束时表达式的值。如果该值在digest循环的时候设置,稍后在相同的循环中它被设置成undefined,那么表达式不满足稳定的条件,它会被继续监视。

  1. 给定一个以::开头的表达式,当digest进入后,expression被进行脏检查,存储表达式的值为V。
  2. 如果V不是undefined,把表达式标记为稳定的,并且分配一个任务,这个任务在退出digest循环时,注销该表达式的watch。
  3. 继续处理digest循环
  4. 当digest完成之后并且所有的值都已经解决。开始运行watch注销任务,检查一下表达式的值是否稳定的。如果是,那么注销掉watch,如果不是,保留这个watch在digest循环中,开始步骤1的循环。

怎样用好一次性绑定的优势

如果表达式在设置后不会更改,则是一次性绑定的最佳选择。这里有三个例子:

当插补文本或者属性:

<div name="attr: {{::color}}">text: {{::name | uppercase}}</div>

当我们使用双向绑定指令而参数不会更改时:

someModule.directive('someDirective',function() {
  return {
    scope: {
      name: '=',color: '@'
    },template: '{{name}}: {{color}}'
  };
});
<div some-directive name="::myName" color="My color is {{::myColor}}"></div>

当我使用有一串表达式的指令时:

<ul> <li ng-repeat="item in ::items | orderBy:'name'">{{item.name}};</li> </ul>





如果我的文章对您有帮助,请用支付宝打赏:

angular学习八—— Expressions的更多相关文章

  1. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  2. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

  3. 利用require.js与angular搭建spa应用的方法实例

    这篇文章主要给大家介绍了关于利用require.js与angular搭建spa应用的方法实例,文中通过示例代码给大家介绍的非常详细,对大家的理解和学习具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。

  4. 详解Angular动态组件

    本文主要介绍了Angular动态组件,对此感兴趣的同学,可以亲自实验一下。

  5. 详解如何使用webpack+es6开发angular1.x

    本篇文章主要介绍了详解如何使用webpack+es6开发angular1.x,具有一定的参考价值,有兴趣的可以了解一下

  6. angular2系列之路由转场动画的示例代码

    本篇文章主要介绍了angular2系列之路由转场动画的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 一种angular的方法级的缓存注解(装饰器)

    本篇文章主要介绍了一种angular的方法级的缓存注解(装饰器),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. 动手写一个angular版本的Message组件的方法

    本篇文章主要介绍了动手写一个angular版本的Message组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. angular forEach方法遍历源码解读

    这篇文章主要为大家详细了angular forEach方法遍历源码,forEach()方法用于遍历对象或数组,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Angular的MVC和作用域

    本文主要Angular的MVC和作用域进行详细分析介绍,具有一定的参考价值,下面跟着小编一起来看下吧

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部