《AngularJS权威教程》笔记(6-7)——表达式、过滤器

1. 表达式

{{}}符号将一个变量绑定到$scope上的写法本质上就是一个表达式{{expression}}。当用$watch进行监听时,AngularJS会对表达式或者函数进行运算。

(1) 解析AngularJS表达式——$parse

AngularJS通过$parse这个内部服务来进行表达式的运算。这个过程允许我们访问定义在$scope上的原始javaScript数据和函数。

$parse服注入到控制器中,然后调用它就可以实现手动解析表达式。下面这个例子就是在input中输入内容在下方复现的功能。

<div ng-app='myApp'>
 <div ng-controller="MyController">
    <input type="text" ng-model='expr' placeholder="Enter an expression">
    <h2>{{parseValue}}</h2>
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope,$parse){
  $scope.$watch('expr',function(newVal,oldVal,scope){
    if(newVal!==oldVal){
      //注意!!此处参数是‘expr’不是newVal,书上写错了,或者低版本可以用
      var parseFun=$parse('expr');
      $scope.parseValue=parseFun(scope);
    }
  });
});

(2) 插值字符串——$interpolate

AngularJS中,有手动运行模板编译的能力。例如,插值允许计入作用域上的某个条件实时更新文本字符串。需要在对象中注入$interpolate服务。

$interpolate服务可以接受三个函数,第一个参数必需。

参数名类型描述
text字符串一个包含字符插值标记的字符串
mustHaveExpression布尔型如果将这个参数设为true,当传入的字符串中不含有表达式时会返回null
trustedContext字符串AngularJS会对已经进行过字符插值操作的字符串通过$sec.getTrusted()方法进行严格的上下文转义

来看这个例子。{{previeText}}也就是textarea中的内部文本,可以把{{to}}当做一个变量来使用,并对文本的变化进行实时更新。
这里写图片描述

 <div ng-app='myApp'>
  <div ng-controller="MyController">
    <input type="email" ng-model='to' placeholder="Recipient">
    <textarea ng-model="emailBody"></textarea>
    <pre>{{previewText}}</pre>
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope,$interpolate){
  $scope.$watch('emailBody',function(body){
    if(body){
      var template=$interpolate(body);
      $scope.previewText=template({to: $scope.to});
    }
  });
});

如果需要在文本中使用不同于{{}}的符号来标识表达式的开始和结束,可以在$interpolateProvider中配置。此处略过具体方法。

2. 过滤器

(1)简介及用法

过滤器用来格式化需要展示给用户的数据。Angular有内置的过滤器,同时也可以自定义。在HTML模板绑定符号{{}}内通过|符号来调用过滤器。

[1] HTML形式过滤器

例如,字符串转换成大写,可以使用过滤器{{name| uppercase}}

以HTML形式使用过滤器时,如果需要传递参数给过滤器,只要在过滤器名字后面加冒号。如果有多个参数,在每个参数后面加入冒号。

例如,限制小数点后位数,写上:2可以将2作为参数传递。
{{123.456789 | number:2}}

[2] JS中的过滤器

在JavaScript中可以通过$filter来调用过滤器。如下例子,转为小写:
这里写图片描述

<div ng-app='myApp'>
  <div ng-controller="MyController">
    <input type="text" ng-model='inputContent'>
    <p>{{contentShow}}</p>
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope,$filter){
   $scope.$watch('inputContent',function(content){
     var filterFun=$filter('lowercase');
     $scope.contentShow=filterFun(content);
   });
 });

(2) 内置过滤器

[1] currency

将数值格式化为货币格式。例如:{{123 | currency}}
currency过滤器允许设置货币符号。默认情况采用客户端所处区域的货币符号。

[2] date

将日期格式化成需要格式。默认采用mediumDate格式。可以自定义。

<div ng-app='myApp'>
  <div ng-controller="MyController">
    <p>{{today|date:'medium'}}</p>
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope,$filter){
  $scope.today = new Date();
});

上例得到的结果是:Mar 19, 2018 4:39:26 PM。替换不同过滤器,得到以下结果。

1) 显示方式
<p>{{today|date:'medium'}}</p>      <!--Mar 19, 2018 4:46:32 PM-->
<p>{{today|date:'short'}}</p>       <!--3/19/18 4:46 PM-->
<p>{{today|date:'fullDate'}}</p>    <!--Monday, March 19, 2018-->
<p>{{today|date:'longDate'}}</p>    <!--March 19, 2018-->
<p>{{today|date:'mediumDate'}}</p>  <!--Mar 19, 2018-->
<p>{{today|date:'mediumTime'}}</p>  <!--4:46:32 PM-->
<p>{{today|date:'shortTime'}}</p>   <!--4:46 PM-->
2) 年格式化
<p>{{today|date:'yyyy'}}</p> <!--2018-->
<p>{{today|date:'yy'}}</p>   <!--18-->
<p>{{today|date:'y'}}</p>    <!--2018-->
3) 月格式化
<!-- 英文月份 -->
<p>{{today|date:'MMMM'}}</p> <!--March-->
<!-- 英文月份简写 -->
<p>{{today|date:'MMM'}}</p>  <!--Mar-->
<!-- 数字月份 -->
<p>{{today|date:'MM'}}</p>   <!--03-->
<!-- 一年中的第几个月份 -->
<p>{{today|date:'M'}}</p>    <!--3-->
4) 日期格式化
<!-- 数字日 -->
<p>{{today|date:'dd'}}</p>   <!--19-->
<!-- 一个月中第几天 -->
<p>{{today|date:'d'}}</p>    <!--19-->
<!-- 英文星期 -->
<p>{{today|date:'EEEE'}}</p> <!--Monday-->
<!-- 英文星期简写 -->
<p>{{today|date:'EEE'}}</p>  <!--Mon-->
5) 小时格式化
<!-- 24小时制数字小时 -->
<p>{{today|date:'HH'}}</p>  <!--17-->
<!-- 一天中第几个小时 -->
<p>{{today|date:'H'}}</p>   <!--17-->
<!-- 12小时制数字小时 -->
<p>{{today|date:'hh'}}</p>  <!--05-->
<!--上午或者下午的第几个小时-->
<p>{{today|date:'h'}}</p>   <!--5-->
6) 分钟格式化
<!-- 数字分钟数 -->
<p>{{today|date:'mm'}}</p> <!--05-->
<!-- 一小时中的第几分钟 -->
<p>{{today|date:'m'}}</p>  <!--5-->
7) 秒数格式化
<!-- 数字秒数 -->
<p>{{today|date:'ss'}}</p>   <!--08-->
<!-- 一小时中的第几秒 -->
<p>{{today|date:'m'}}</p>    <!--7-->
<!-- 毫秒数 -->
<p>{{today|date:'.sss'}}</p> <!--.623-->
8) 字符格式化
<!-- 上下午标识 -->
<p>{{today|date:'a'}}</p> <!--PM-->
<!-- 四位时区标识 -->
<p>{{today|date:'Z'}}</p> <!--+0800-->
9) 自定义示例
 <p>{{today|date:'MMMd, y'}}</p>      <!--Mar19, 2018-->
 <p>{{today|date:'EEEE, d, M'}}</p>   <!--Monday, 19, 3-->
 <p>{{today|date:'hh:mm:ss.sss'}}</p> <!--05:12:21.907-->

[3] filter

filter过滤器可以从给定数组中选择一个子集,并生成一个新数组返回。

1) 参数1

filter这个过滤器的第一个参数可以是字符串、对象或者是一个用来从数组中选择元素的函数。

字符串

返回所有包含这个字符串的元素。若想返回不包含该字符串的元素,在参数前加

<p>{{['a','bcd','abc'] | filter:'a'}}</p>   <!-- ["a","abc"] -->
<p>{{['a','bcd','abc'] | filter:'!a'}}</p>  <!-- ["bcd"] -->
对象

将待过滤对象属性与对象中的同名属性比较,如果是字符串会判断是否包含该字符。如果需比较全部属性,将$当做键名。

<div ng-app='myApp'>
  <div ng-controller="MyController">
    <p>{{ myObject| filter:{age: '18'} }}</p>  <!-- [{"name":"Joyce","age":"18"},{"name":"Frank","age":"18"}] -->
    <p>{{ myObject| filter:{name: 'a'} }}</p>  <!-- [{"name":"Frank","age":"18"},{"name":"Diana","age":"16"}] -->
    <p>{{ myObject| filter:{$: '6'} }}</p>     <!-- [{"name":"Diana","age":"16"}] -->
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope){
  $scope.myObject=[{
      name: 'Joyce',
      age: '18'
    },
    {
      name: 'Frank',
      age: '18'
    },
    {
      name: 'Diana',
      age: '16'
    }];
});
函数

对每个元素都执行这个函数,返回非假值的元素会出现在新的数组中并返回。

<div ng-app='myApp'>
  <div ng-controller="MyController">
    <p>{{ ['Amy','like','to','travel']| filter:isCapitalized }}</p>  <!-- ["Amy"] -->
  </div>
</div>
angular.module('myApp',[])
.controller('MyController',function($scope){
  $scope.isCapitalized=function(str){
    return str[0]==str[0].toUpperCase();
  }
});
2) 参数2(optional)
true

用angular.equals(expected,actual)对两个值进行严格比较。

<p>{{['JaSon','AmY','JOE'] | filter:'amy':true}}</p>   <!-- [] -->
false

进行不区分大小写的子字符串比较。(书上说是区分,实践后发现不区分true时会)

<p>{{['JaSon','AmY','JOE'] | filter:'amy':false}}</p>  <!-- ["AmY"] -->
函数

运行这个函数,如果返回真值就接受这个元素。
如果两个参数都是函数的情况,似乎有个没有生效,看下面这个例子,不太明白为啥结果是:[“Amy”,”Travel”]。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <script src="/js/angular.min.js"></script>
  </head>
  <body>
    <div ng-app='myApp'>
      <div ng-controller="MyController">
        <p>{{ ['Amy','like','to','Travel']| filter:isCapitalized:lengthShort }}</p> 
      </div>
    </div>
  </body>
  <script>
     angular.module('myApp',[])
      .controller('MyController',function($scope){
        $scope.isCapitalized=function(str){
          console.log('is');
          return str[0]==str[0].toUpperCase();
        }
        $scope.lengthShort=function(str){
          console.log('short');
          return str.length<5;
        }
      });
  </script>
</html>

[4] json

json过滤器可以将一个JSON或者JavaScript对象转换成字符串。这样的转换对调试非常有帮助,相当于JSON.stringify()
{{ {'name':'Joyce','age':'18'} | json}}
结果为:{ “name”: “Joyce”, “age”: “18” }

[5] limitTo

根据传入参数生成新的数组或字符串。

截取方式:

  • 数值:字符串截取字符数量;数组截取数组元素数量
  • 正负:正数从前截取;附属从后截取

如果数值大于原长度,则返回原始字符串或者数组。

<p>{{ 'Hello World'| limitTo:20 }}</p>               <!-- Hello World-->
<p>{{ 'Hello World'| limitTo:5 }}</p>                <!-- Hello -->
<p>{{ 'Hello World'| limitTo:-5 }}</p>               <!-- World -->
<p>{{ ['Amy','like','to','Travel']| limitTo:2 }}</p> <!-- ["Amy","like"]-->
<p>{{ ['Amy','like','to','Travel']| limitTo:-2 }}</p> <!-- ["to","Travel"] -->

[6] lowercase、uppercase

将字符串转为小写或者大写。

<p>{{ 'Hello World'| lowercase }}</p><!--hello world-->
<p>{{ 'Hello World'| uppercase }}</p><!--HELLO WORLD-->

[7] number

将数字格式化为文本。第二个参数可选,控制小数点后的位数(四舍五入)。

<p>{{ 12345678.9| number }}</p>     <!--12,345,678.9-->
<p>{{ 12345678.9052| number:2 }}</p><!--12,345,678.91-->

[8] orderBy

对指定数组进行排序。第一个参数必需,第二个可选。
以下例子都用以下数据作为数据源。

$scope.myData=[
  {name:'Amy',score:100},
  {name:'Jason',score:80},
  {name:'zoe',score:90},
  {name:'Belly',score:90},
];
1) 参数1
函数

该函数会被当做待排序对象的getter方法。

字符串

根据这个字符串进行数组的排序。可以传入+或者-来强制升序或降序。

<p>{{ myData | orderBy:'score' }}</p>
<p>{{ myData | orderBy:'+score' }}</p>
<p>{{ myData | orderBy:'-score' }}</p>

结果:
[{“name”:”Jason”,”score”:80},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Amy”,”score”:100}]

[{“name”:”Jason”,”score”:80},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Amy”,”score”:100}]

[{“name”:”Amy”,”score”:100},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Jason”,”score”:80}]

数组

根据数组序列的表达式进行排列。例如在score一致的情况下,就根据name排序:

<p>{{ myData | orderBy:'score' }}</p>
<p>{{ myData | orderBy:['score','name'] }}</p>

结果:
[{“name”:”Jason”,”score”:80},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Amy”,”score”:100}]

[{“name”:”Jason”,”score”:80},{“name”:”Belly”,”score”:90},{“name”:”zoe”,”score”:90},{“name”:”Amy”,”score”:100}]

2) 参数2(optional)

是否逆向,true: 逆向;false: 不逆向

<p>{{ myData | orderBy:'score' }}</p>
<p>{{ myData | orderBy:'score':true }}</p>
<p>{{ myData | orderBy:'-score':true }}</p>
<p>{{ myData | orderBy:'score':false }}</p>

结果:
[{“name”:”Jason”,”score”:80},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Amy”,”score”:100}]

[{“name”:”Amy”,”score”:100},{“name”:”Belly”,”score”:90},{“name”:”zoe”,”score”:90},{“name”:”Jason”,”score”:80}]

[{“name”:”Jason”,”score”:80},{“name”:”Belly”,”score”:90},{“name”:”zoe”,”score”:90},{“name”:”Amy”,”score”:100}]

[{“name”:”Jason”,”score”:80},{“name”:”zoe”,”score”:90},{“name”:”Belly”,”score”:90},{“name”:”Amy”,”score”:100}]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值