AngularJS 过滤器
AngularJS 过滤器 (Filter) 学习笔记过滤器用于在视图中格式化数据而不改变原始数据模型。它们可以在表达式、指令和控制器中使用是 AngularJS 数据展示层的重要工具。一、过滤器的基本概念1. 什么是过滤器定义用于转换数据格式的函数。作用格式化日期、数字、货币、数组排序、字符串转换等。使用位置模板HTML中的{{ }}表达式。ng-bind指令。控制器和服务中通过$filter服务调用。2. 语法{{ expression | filterName }} {{ expression | filterName : argument1 : argument2 }}二、内置过滤器详解1.currency- 货币格式化{{ 1234.56 | currency }}!-- $1,234.56 --{{ 1234.56 | currency:¥ }}!-- ¥1,234.56 --{{ 1234.56 | currency:€ : 0 }}!-- €1235 (0位小数) --参数符号默认$。小数位数默认 2。2.number- 数字格式化{{ 1234567.89 | number }}!-- 1,234,567.89 --{{ 1234567.89 | number:0 }}!-- 1,234,568 --{{ 1234567.89 | number:2 }}!-- 1,234,567.89 --参数小数位数。3.date- 日期格式化{{ 1441843200000 | date:yyyy-MM-dd }}!-- 2015-09-10 --{{ 1441843200000 | date:MM/dd/yyyy h:mma }}!-- 09/10/2015 12:00AM --{{ 1441843200000 | date:shortTime }}!-- 12:00 AM --常用格式yyyy-MM-dd年月日HH:mm:ss时分秒shortDate短日期fullDate完整日期4.json- JSON 格式化{{ user | json }}!-- 输出: {name:John,age:25} --用途调试对象数据。5.lowercase/uppercase- 大小写转换{{ Hello World | lowercase }}!-- hello world --{{ Hello World | uppercase }}!-- HELLO WORLD --6.limitTo- 限制长度{{ Hello World | limitTo:5 }}!-- Hello --{{ [1,2,3,4,5] | limitTo:3 }}!-- [1,2,3] --{{ Hello World | limitTo:-5 }}!-- World (从末尾取) --参数正数从开头取负数从末尾取。7.orderBy- 数组排序!-- 按名字升序 --ling-repeatuser in users | orderBy:name{{ user.name }}/li!-- 按年龄降序 --ling-repeatuser in users | orderBy:age:true{{ user.name }} ({{ user.age }})/li!-- 多字段排序 --ling-repeatuser in users | orderBy:[age, name]{{ user.name }}/li参数排序字段字符串或数组。是否降序true为降序默认false。比较函数自定义。8.filter- 数组/对象过滤!-- 过滤包含 John 的用户 --ling-repeatuser in users | filter:John{{ user.name }}/li!-- 过滤特定属性 --ling-repeatuser in users | filter:{age:25}{{ user.name }}/li!-- 复杂过滤 --ling-repeatuser in users | filter:{name:John, age:25}{{ user.name }}/li!-- 自定义过滤函数 --ling-repeatuser in users | filter:isAdult{{ user.name }}/li// 控制器中定义过滤函数$scope.isAdultfunction(user){returnuser.age18;};9.orderBy与filter组合使用ling-repeatuser in users | filter:{age:25} | orderBy:name{{ user.name }}/li三、自定义过滤器1. 定义过滤器app.filter(reverse,function(){returnfunction(input){if(!input)returninput;returninput.split().reverse().join();};});2. 在模板中使用{{ Hello | reverse }}!-- olleH --3. 带参数的自定义过滤器app.filter(truncate,function(){returnfunction(input,length,suffix){if(!input)returninput;if(input.lengthlength)returninput;returninput.substring(0,length)(suffix||...);};});{{ Hello World | truncate:5:... }}!-- Hello... --4. 在控制器中使用过滤器app.controller(MyCtrl,function($scope,$filter){$scope.reverseText$filter(reverse)(Hello);$scope.truncated$filter(truncate)(Hello World,5,...);});5. 在指令中使用过滤器app.directive(myDirective,function($filter){return{link:function(scope,element,attrs){varformatted$filter(currency)(1234.56);element.text(formatted);}};});四、过滤器链可以连续使用多个过滤器{{ 1234.567 | number:2 | currency:¥ }}!-- ¥1,234.57 --{{ Hello World | lowercase | limitTo:5 }}!-- hello --五、性能优化1. 避免在循环中频繁调用复杂过滤器!-- ❌ 性能差每次脏检查都执行 --ling-repeatitem in items{{ item.value | complexFilter }}/li!-- ✅ 优化在控制器中预处理 --ling-repeatitem in items{{ item.formattedValue }}/li// 控制器中预处理$scope.items.forEach(function(item){item.formattedValue$filter(complexFilter)(item.value);});2. 使用一次性绑定AngularJS 1.3!-- 只在初始化时执行一次 --{{ ::user.name | uppercase }}3. 避免在过滤器中修改原始数据// ❌ 错误修改了原始数组app.filter(myFilter,function(){returnfunction(input){input.reverse();// 修改了原数组returninput;};});// ✅ 正确返回新数组app.filter(myFilter,function(){returnfunction(input){if(!input)returninput;returninput.slice().reverse();// 创建副本};});六、常见应用场景1. 分页与排序divng-controllerListCtrlinputng-modelsearchTextplaceholder搜索...tabletrng-repeatuser in users | filter:searchText | orderBy:nametd{{ user.name }}/tdtd{{ user.age | number }}/tdtd{{ user.birthDate | date:yyyy-MM-dd }}/td/tr/table/div2. 货币与数字显示divng-controllerPriceCtrlp单价{{ price | currency }}/pp数量{{ quantity | number }}/pp总价{{ (price * quantity) | currency }}/p/div3. 日期格式化divng-controllerDateCtrlp创建时间{{ createTime | date:yyyy年MM月dd日 HH:mm }}/pp相对时间{{ createTime | date:shortTime }}/p/div4. 数组切片divng-controllerListCtrlp前5项{{ items | limitTo:5 | json }}/pp最后3项{{ items | limitTo:-3 | json }}/p/div七、最佳实践1. 保持过滤器纯函数不修改输入数据。不依赖外部状态。相同输入始终返回相同输出。2. 避免复杂逻辑复杂逻辑应放在控制器或 Service 中。过滤器只负责格式化。3. 使用有意义的名称// ✅ 好app.filter(currency,...);app.filter(date,...);// ❌ 不好app.filter(f1,...);4. 错误处理app.filter(safeJson,function(){returnfunction(input){if(!input)return;try{returnJSON.stringify(input,null,2);}catch(e){returnInvalid JSON;}};});5. 模块化管理// filters/currency.jsangular.module(myApp.filters,[]).filter(currency,function(){...});// filters/date.jsangular.module(myApp.filters).filter(date,function(){...});// app.jsangular.module(myApp,[myApp.filters]);八、常见问题与解决方案问题原因解决方案过滤器不生效语法错误、参数类型不对检查参数类型和语法性能问题复杂过滤器在循环中频繁调用预处理数据或使用一次性绑定数据被修改过滤器修改了原始数据返回新对象/数组不修改原数据过滤器无法注入服务在过滤器中直接注入服务使用$filter服务或工厂模式中文乱码日期格式或编码问题检查数据源编码和格式九、总结AngularJS 过滤器的核心要点用途格式化数据不改变原始模型。内置过滤器currency,number,date,json,orderBy,filter等。自定义过滤器通过app.filter()定义支持参数。使用位置模板、控制器$filter、指令。性能优化避免复杂逻辑使用一次性绑定预处理数据。最佳实践保持纯函数错误处理模块化管理。通过合理使用过滤器可以大大简化视图代码提高数据展示的可读性和维护性。