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 - 数组排序
<!-- 按名字升序 -->
<li ng-repeat="user in users | orderBy:'name'">
    {{ user.name }}
</li>

<!-- 按年龄降序 -->
<li ng-repeat="user in users | orderBy:'age':true">
    {{ user.name }} ({{ user.age }})
</li>

<!-- 多字段排序 -->
<li ng-repeat="user in users | orderBy:['age', 'name']">
    {{ user.name }}
</li>
  • 参数
    • 排序字段(字符串或数组)。
    • 是否降序(true 为降序,默认 false)。
    • 比较函数(自定义)。
8. filter - 数组/对象过滤
<!-- 过滤包含 "John" 的用户 -->
<li ng-repeat="user in users | filter:'John'">
    {{ user.name }}
</li>

<!-- 过滤特定属性 -->
<li ng-repeat="user in users | filter:{age:25}">
    {{ user.name }}
</li>

<!-- 复杂过滤 -->
<li ng-repeat="user in users | filter:{name:'John', age:25}">
    {{ user.name }}
</li>

<!-- 自定义过滤函数 -->
<li ng-repeat="user in users | filter:isAdult">
    {{ user.name }}
</li>
// 控制器中定义过滤函数
$scope.isAdult = function(user) {
    return user.age >= 18;
};
9. orderByfilter 组合使用
<li ng-repeat="user in users | filter:{age:25} | orderBy:'name'">
    {{ user.name }}
</li>

三、自定义过滤器

1. 定义过滤器
app.filter('reverse', function() {
    return function(input) {
        if (!input) return input;
        return input.split('').reverse().join('');
    };
});
2. 在模板中使用
{{ "Hello" | reverse }}  <!-- olleH -->
3. 带参数的自定义过滤器
app.filter('truncate', function() {
    return function(input, length, suffix) {
        if (!input) return input;
        if (input.length <= length) return input;
        return input.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) {
            var formatted = $filter('currency')(1234.56);
            element.text(formatted);
        }
    };
});

四、过滤器链

可以连续使用多个过滤器:

{{ 1234.567 | number:2 | currency:"¥" }}  <!-- ¥1,234.57 -->
{{ "Hello World" | lowercase | limitTo:5 }}  <!-- hello -->

五、性能优化

1. 避免在循环中频繁调用复杂过滤器
<!-- ❌ 性能差:每次脏检查都执行 -->
<li ng-repeat="item in items">{{ item.value | complexFilter }}</li>

<!-- ✅ 优化:在控制器中预处理 -->
<li ng-repeat="item 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() {
    return function(input) {
        input.reverse(); // 修改了原数组
        return input;
    };
});

// ✅ 正确:返回新数组
app.filter('myFilter', function() {
    return function(input) {
        if (!input) return input;
        return input.slice().reverse(); // 创建副本
    };
});

六、常见应用场景

1. 分页与排序
<div ng-controller="ListCtrl">
    <input ng-model="searchText" placeholder="搜索...">
    
    <table>
        <tr ng-repeat="user in users | filter:searchText | orderBy:'name'">
            <td>{{ user.name }}</td>
            <td>{{ user.age | number }}</td>
            <td>{{ user.birthDate | date:"yyyy-MM-dd" }}</td>
        </tr>
    </table>
</div>
2. 货币与数字显示
<div ng-controller="PriceCtrl">
    <p>单价:{{ price | currency }}</p>
    <p>数量:{{ quantity | number }}</p>
    <p>总价:{{ (price * quantity) | currency }}</p>
</div>
3. 日期格式化
<div ng-controller="DateCtrl">
    <p>创建时间:{{ createTime | date:"yyyy年MM月dd日 HH:mm" }}</p>
    <p>相对时间:{{ createTime | date:"shortTime" }}</p>
</div>
4. 数组切片
<div ng-controller="ListCtrl">
    <p>前5项:{{ items | limitTo:5 | json }}</p>
    <p>最后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() {
    return function(input) {
        if (!input) return '';
        try {
            return JSON.stringify(input, null, 2);
        } catch (e) {
            return 'Invalid JSON';
        }
    };
});
5. 模块化管理
// filters/currency.js
angular.module('myApp.filters', [])
    .filter('currency', function() { ... });

// filters/date.js
angular.module('myApp.filters')
    .filter('date', function() { ... });

// app.js
angular.module('myApp', ['myApp.filters']);

八、常见问题与解决方案

问题 原因 解决方案
过滤器不生效 语法错误、参数类型不对 检查参数类型和语法
性能问题 复杂过滤器在循环中频繁调用 预处理数据或使用一次性绑定
数据被修改 过滤器修改了原始数据 返回新对象/数组,不修改原数据
过滤器无法注入服务 在过滤器中直接注入服务 使用 $filter 服务或工厂模式
中文乱码 日期格式或编码问题 检查数据源编码和格式

九、总结

AngularJS 过滤器的核心要点:

  1. 用途:格式化数据,不改变原始模型。
  2. 内置过滤器currency, number, date, json, orderBy, filter 等。
  3. 自定义过滤器:通过 app.filter() 定义,支持参数。
  4. 使用位置:模板、控制器($filter)、指令。
  5. 性能优化:避免复杂逻辑,使用一次性绑定,预处理数据。
  6. 最佳实践:保持纯函数,错误处理,模块化管理。

通过合理使用过滤器,可以大大简化视图代码,提高数据展示的可读性和维护性。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐