Как применить фильтр к нескольким объектам с помощью AngularJS?

У меня есть объект пользователя, определенный, как показано ниже.

$scope.users = [{id: 1, name: 'Adam', friends: [{name: 'John', age: 21, sex: 'M'}, {name: 'Brad', age: 32, sex: 'M'}]}]

Тогда у меня есть следующий код:

<div ng-repeat="user in users>
 <input type="text" ng-model="searchText">
 <div ng-repeat="friend in user.friends | filter:searchText">
  {{user.name}} {{friend.name}} {{friend.age}}
 </div>
</div>

Теперь, когда я набираю в текстовом поле текст: 'searchText', я хочу, чтобы фильтр отображал имя пользователя и имя/возраст друга. Может ли кто-нибудь помочь мне с тем, как это сделать?

Если я прав, то я думаю, что мне нужно создать собственный фильтр для этого или есть другой способ сделать это?


person Chubby Boy    schedule 12.12.2012    source источник


Ответы (2)


Поскольку вы хотите фильтровать сразу две вещи — некоторые свойства массива друзей и пользователя, — вам нужно создать собственный пользовательский фильтр, который принимает 2 дополнительных параметра:

myApp.filter('myFilter', function() {
  return function(friends, searchText, username) {
    var searchRegx = new RegExp(searchText, "i");
    if ((searchText == undefined) || (username.search(searchRegx) != -1)) {
        return friends;
    }
    var result = [];
    for(i = 0; i < friends.length; i++) {
        if (friends[i].name.search(searchRegx) != -1 || 
            friends[i].age.toString().search(searchText) != -1) {
            result.push(friends[i]);
        }
    }
    return result;
  }
});

Затем назовите это так:

<div ng-repeat="user in users">
   <input type="text" ng-model="searchText">
   <div ng-repeat="friend in user.friends | myFilter:searchText:user.name">
      {{user.name}} {{friend.name}} {{friend.age}}
    </div>
</div>

«:searchText:user.name» — это способ передачи дополнительных аргументов пользовательскому фильтру.

Скрипка.

person Mark Rajcok    schedule 12.12.2012
comment
Большое спасибо Марк! Но этот filterFilter(friends, searchText) будет фильтровать все объекты друзей, то есть имя, возраст и пол, или только имя и возраст. Мое требование: я хочу, чтобы только «имя» и «возраст» были доступны для поиска, а результаты были отфильтрованы только по этим двум объектам друзей, так как это отображаемые поля, а не «пол». - person Chubby Boy; 13.12.2012
comment
Я понимаю, насколько это старо... но что может происходить, когда мой ввод "searchText" всегда не определен внутри фильтра? Проблемы с масштабированием, очевидно, но почему? - person Clev3r; 13.09.2013
comment
@Clever, я предлагаю вам создать новый вопрос, который включает ваш HTML и фильтр. - person Mark Rajcok; 13.09.2013
comment
Это было очень полезно для меня, спасибо! Единственное предостережение, которое я бы добавил, которое я пропустил на первый взгляд, это то, что когда вы указываете фильтр в параметрах ng-repeat, убедитесь, что вы заменили обычный filter: на имя вашего фильтра (он же myFilter:‹param1›‹param2›) . Кроме того, не уверен на 100%, что вы делаете в первой строке вашей функции возврата, проверяя букву i в searchText. Мне это не нужно в моем решении, поэтому я его убрал. - person shaunpickford; 24.06.2014
comment
@shaunpickford, я флаг RegExp это означает игнорировать регистр. - person Mark Rajcok; 25.06.2014

http://docs.angularjs.org/api/ng.filter:filter

<div ng-repeat="user in users>
 <input type="text" ng-model="search.$">
 <div ng-repeat="friend in user.friends | filter:search">
  {{user.name}} {{friend.name}} {{friend.age}}
 </div>
</div>
person Umur Kontacı    schedule 12.12.2012
comment
Спасибо, fastreload! Это помогает! Но для каких объектов это будет фильтровать? Будет ли этот фильтр фильтроваться только по имени пользователя и имени и возрасту друга? - person Chubby Boy; 12.12.2012
comment
Как описано в документации, он будет искать все свойства объектов внутри массива объектов. Вы можете думать о $ как о волшебном подстановочном знаке. - person Umur Kontacı; 12.12.2012
comment
Спасибо, fastreload! Здесь в моем объекте друга у меня есть три атрибута: имя, возраст и пол. Но я не хочу, чтобы секс был доступен для поиска. Есть ли способ добиться этого? - person Chubby Boy; 12.12.2012
comment
Вам нужно создать функцию, которая принимает элемент массива и возвращает значение true/false в зависимости от ваших потребностей, и передать имя функции в качестве параметра filters. функция: функция-предикат может использоваться для написания произвольных фильтров. Функция вызывается для каждого элемента массива. Конечным результатом является массив тех элементов, для которых предикат вернул true. - person Umur Kontacı; 12.12.2012