Skip to content

Latest commit

 

History

History
234 lines (157 loc) · 6.41 KB

04.md

File metadata and controls

234 lines (157 loc) · 6.41 KB

四、过滤器

角度过滤器通常用于格式化模板绑定中的表达式。它们将输入数据转换成新的格式化数据类型。

用货币过滤器格式化字符串

问题

您希望使用本地化的货币标签来格式化货币金额。

溶液

使用内置的currency过滤器,并确保为用户的语言加载相应的区域设置文件:

    <html>
    <head>
    <meta charset='utf-8'>
    <script src="js/angular.js"></script>
    <script src="js/angular-locale_de.js"></script>
    </head>
    <body ng-app>
    <input type="text" ng-model="amount" placeholder="Enter amount"/>
    <p>Default Currency: {{ amount | currency }}</p>
    <p>Custom Currency: {{ amount | currency: "Euro" }}</p>
    </body>
    </html>

输入一个数量,它将使用 Angular 的默认区域显示。

你可以在 GitHub 上找到完整的例子。

讨论

在我们的示例中,我们显式加载了德语区域设置,因此,默认格式将是德语。默认情况下,英语语言环境是附带的,因此不需要包含 angular-locale_en.js 文件。如果删除脚本标签,您将看到格式改为英语。这意味着,为了使本地化的应用程序正常工作,您需要加载相应的区域设置文件。所有可用的语言环境文件都可以在 GitHub 上看到。

实现自定义过滤器以恢复输入字符串

问题

您希望恢复用户的文本输入。

溶液

实现一个自定义过滤器,它可以还原输入:

    <body ng-app="MyApp">
    <input type="text" ng-model="text" placeholder="Enter text"/>
    <p>Input: {{ text }}</p>
    <p>Filtered input: {{ text | reverse }}</p>
    </body>

    var app = angular.module("MyApp", []);

    app.filter("reverse", function() {
    return function(input) {
    var result = "";
    input = input || "";
    for (var i=0; i<input.length; i++) {
    result = input.charAt(i) + result;
    }
    return result;
    };
    });

你可以在 GitHub 上找到完整的例子。

讨论

Angular 的过滤器函数需要一个过滤器名称和一个函数作为参数。该函数必须返回实现业务逻辑的实际过滤器函数。在这个例子中,它只有一个input参数。for循环反转输入后,将返回结果。

将配置参数传递给过滤器

问题

您希望通过引入配置参数来定制您的过滤器。

溶液

角度过滤器可以作为参数的散列传递,可以在过滤器函数中直接访问:

    <body ng-app="MyApp">
    <input type="text" ng-model="text" placeholder="Enter text"/>
    <p>Input: {{ text }}</p>
    <p>Filtered input: {{ text | reverse: { suffix: "!"} }}</p>
    </body>

    var app = angular.module("MyApp", []);

    app.filter("reverse", function() {
    return function(input, options) {
    input = input || "";
    var result = "";
    var suffix = options["suffix"] || "";

    for (var i=0; i<input.length; i++) {
    result = input.charAt(i) + result;
    }

    if (input.length > 0) result += suffix;

    return result;
    };
    });

你可以在 GitHub 上找到完整的例子。

讨论

后缀!作为一个选项传递给过滤器功能,并附加到输出中。请注意,我们检查是否存在实际输入,因为我们不想在没有任何输入的情况下呈现后缀。

过滤 DOM 节点列表

问题

您希望过滤名称列表。

溶液

除了字符串作为输入,Angular 的过滤器还可以处理数组:

    <body ng-app="MyApp">
    <ul ng-init="names = ['Peter', 'Anton', 'John']">
    <li ng-repeat="name in names | exclude:'Peter' ">
    <span>{{name}}</span>
    </li>
    </ul>
    </body>

    var app = angular.module("MyApp", []);

    app.filter("exclude", function() {
    return function(input, exclude) {
    var result = [];
    for (var i=0; i<input.length; i++) {
    if (input[i] !== exclude) {
    result.push(input[i]);
    }
    }

    return result;
    };
    });

我们将Peter作为单个参数传递给排除过滤器,该过滤器将渲染除Peter之外的所有名称。

你可以在 GitHub 上找到完整的例子。

讨论

过滤器实现遍历所有名称,并创建一个结果数组,不包括“Peter”。请注意,过滤器函数的实际语法与我们前面的字符串输入示例完全没有变化。

将过滤器链接在一起

问题

您希望将几个过滤器组合成一个结果。

溶液

过滤器可以使用类似 Unix 的管道语法进行链接:

    <body ng-app="MyApp">
    <ul ng-init="names = ['Peter', 'Anton', 'John']">
    <li ng-repeat="name in names | exclude:'Peter' | sortAscending ">
    <span>{{name}}</span>
    </li>
    </ul>
    </body>

讨论

管道符号(|)用于将多个过滤器链接在一起。首先,我们将从名字的初始数组开始。应用exclude过滤器后,数组只包含['Anton', 'John'],然后我们将按升序对名称进行排序。

我把sortAscending过滤器的实现作为一个练习留给读者。

测试过滤器

问题

您希望对新过滤器进行单元测试。让我们从一个简单的过滤器开始,它根据布尔值呈现一个复选标记:

    <body ng-init="data = true">
    <p>{{ data | checkmark}}</p>
    <p>{{ !data | checkmark}}</p>
    </body>

    var app = angular.module("MyApp", []);

    app.filter('checkmark', function() {
    return function(input) {
    return input ? '\u2713' : '\u2718';
    };
    });

溶液

再次使用角种子项目作为引导:

    describe('MyApp Tabs', function() {
    beforeEach(module('MyApp'));

    describe('checkmark', function() {
    it('should convert boolean values to unicode checkmark or cross',
    inject(function(checkmarkFilter) {
    expect(checkmarkFilter(true)).toBe('\u2713');
    expect(checkmarkFilter(false)).toBe('\u2718');
    }));
    });
    });

讨论

beforeEach加载模块,it方法为我们注入过滤功能。注意必须叫checkmarkFilter;否则 Angular 无法正确注入我们的滤镜功能。