Фильтры позволяют провести некоторую предобработку перед выводом данных на страницу, например, отсортировать или как-то изменить набор данных.
Общий способ использования фильтров: {{expression | filter}}
Используя фильтры lowercase
и uppercase
, мы можем приводить содержимое к нижнему и верхнему регистру соответственно. Например,
<h3>{{question.text | lowercase}}</h3>
Фильтр number
позволяет форматировать числа. Например, <div>{{234.5677 | number:1}}</div>
. Результатом
работы данного фильтра будет число 234.6
. Числовой параметр после двоеточия указывает, сколько останется чисел после запятой (условной,
так как в данном случае для разделения целой и дробной части используется точка). Если числовой параметр больше количества разрядов после запятой, то
при выводе число дополняется нулями.
Для форматирования валюты используется фильтр currency
. Например: <div>{{234.5 | currency}}</div>
.
По умолчанию фильтр добавляет значок доллара. Но доллары USA не везде используются, поэтому мы можем изменить символ валюты:
<div>{{234.5 | currency:'RUB'}}</div>
Чтобы вывести дату в определенном формате применяется фильтр date
. В качестве выражения используется количеств миллисекунд,
прошедших с начала эпохи Unix (то есть с 1 января 1970 года). Например: <div>{{1405405678756 | date:'yyyy-MM-dd'}}</div>
Здесь на страницу будет выведена дата 2014-07-15
, соответствующая шаблону yyyy-MM-dd
. Данный фильтр имеет очень много
шаблонов, которые можно посмотреть в документации.
Фильтр orderBy упорядочивает набор объектов по определенному свойству. Так, возьмем проект, созданный в прошлом разделе. Изменим строки, где происходит вывод объектов следующим образом:
<div ng-repeat="answer in question.answers | orderBy:sortparam" class="answer"> <!-- далее остальное содержимое -->
Здесь у нас применяется фильтр orderBy, который использует параметр sortparam
. Добавим определение этого параметра в ранее созданный контроллер
QuestionController:
var myApp=angular.module('myApp'); myApp.controller('QuestionController', function($scope) { $scope.sortparam='rate'; $scope.question={ text: 'Какой js-фреймворк лучше использовать?', author: 'Иван Иванов', date: '20/10/2013', answers:[{ text: 'AngularJS!', author: 'Вова Сидоров', date: '20/10/2013', rate:2 },{ text: 'AngularJS лучше всех', author: 'Олег Кузнецов', date: '20/10/2013', rate:0 },{ text: 'Я бы использовал knockout', author: 'Неизвестный', date: '21/10/2013', rate:0 }] }; $scope.voteUp = function (answer){ answer.rate++; }; $scope.voteDown = function (answer){ answer.rate--; }; });
Строка $scope.sortparam='rate';
указывает, что все объекты будут отсортированы при выводе по значению свойства rate в порядке возрастания.
Если же нам надо поместить сначала те объекты, у которых свойство rate больше, то делаем обратный порядок: $scope.sortparam='-rate';
Теперь применим фильтр limitTo, который ограничивает вывод определенным количеством объектов:
<div ng-repeat="answer in question.answers | orderBy:sortparam | limitTo:2" class="answer"> <!-- далее остальное содержимое -->
Фильтр filter задает параметры и значения фильтрации. Посмотрим на примере. Возьмем проект, сделанный выше, и добавим в него привязку двух выпадающих списков с применением фильтра filter:
<div ng-controller="QuestionController"> <select ng-model="answer.author"> <option ng-repeat="answer in question.answers" >{{answer.author}}</option> </select> <select> <option ng-repeat="selected_answer in question.answers | filter:answer">{{selected_answer.date}}</option> </select> </div>
Здесь первый элемент select привязывается к модели answer.author через ng-model. Второй же осуществляет фильтрацию по выбранной модели. При выборе автора ответа в первом списке во втором автоматически будут отображаться даты всех его ответов. Вывод в элемент select можно заменить выводом в div, ul или другой элемент.
Рассмотрим еще пример с фильтром. Допустим, нам надо через специальное поле ввода динамически получать всех ответчиков, которые соответствуют определенному критерию:
<div ng-controller="QuestionController"> <div class="quest"> <h3>{{question.text}}</h3> <p>{{question.author}} </p> <p><i>{{question.date}}</i></p> </div> <p>Введите ответчика: <input type="text" ng-model="member"></p> <h3>Ответы</h3> <div class="answers"> <div ng-repeat="a in question.answers | filter:{author:member}" class="answer" > <div class="vote"> <a class="vote-up" ng-click="voteUp(a)"></a> <span class="rate">{{a.rate}}</span> <a class="vote-down" ng-click="voteDown(a)"></a> </div> <b>{{a.text}}</b> <p>{{a.author}}</p> <p><i>{{a.date}}</i></p> </div> </div> </div>
Тут все просто: текстовое поле осуществляет привязку к объекту member: ng-model="member"
. Даже если в контроллере мы не установили этот
объект, AngularJS создает его автоматически. А при выводе устанавливаем фильтр по этому объекту: <div ng-repeat="a in question.answers | filter:{author:member}" class="answer" >
.
Причем данный объект учитывается только для свойства author.