Передача аргументов фильтрам angularjs

99

Можно ли передать аргумент функции фильтра, чтобы можно было фильтровать по любому имени?

Что-то вроде

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};
оборотень
источник

Ответы:

223

На самом деле есть другое (может быть, лучшее решение), где вы можете использовать собственный фильтр angular 'filter' и по-прежнему передавать аргументы своему настраиваемому фильтру.

Рассмотрим следующий код:

<div ng-repeat="group in groups">
    <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
        <span>{{friend.name}}</span>
    <li>
</div>

Чтобы это работало, вы просто определяете свой фильтр следующим образом:

$scope.weDontLike = function(name) {
    return function(friend) {
        return friend.name != name;
    }
}

Как вы можете видеть здесь, weDontLike фактически возвращает другую функцию, в области действия которой есть ваш параметр, а также исходный элемент, поступающий из фильтра.

Мне потребовалось 2 дня, чтобы понять, что вы можете это сделать, я еще нигде не видел этого решения.

Checkout обратной полярности из angular.js фильтра , чтобы увидеть , как вы можете использовать это для других полезных операций с фильтром.

Денис Пшенов
источник
Если вашему фильтру требуется несколько аргументов, см. Как вызвать фильтр Angular.js с несколькими аргументами?
nh2
Этот метод также решил странную проблему, когда внутри ng-repeat я не мог передать свои собственные параметры моему фильтру. Что бы я ни делал, они возвращались как указатель и как общая коллекция. Выполнив этот метод возврата, я смог передать свои параметры и по-прежнему загрузить исходный элемент, отличное исправление!
Деннис Смолек
Этот ответ решил мою проблему, когда я не смог передать переменную $ scope в качестве параметра функции фильтра. Лучшее решение. Проголосовали!
valafar 08
Если бы я мог проголосовать за это более одного раза, я бы удостоверился, что это был самый популярный ответ в истории SO. Это выматывает меня из себя годами ... и затем я нахожу ответ (которому уже 2 года) ... Большое вам спасибо.
PKD
Все еще полезно в 2019 году! Большое спасибо.
ashilon
76

Насколько я понимаю, вы не можете передавать аргументы функции фильтра (при использовании фильтра «фильтр»). Что вам нужно сделать, так это написать собственный фильтр, например:

.filter('weDontLike', function(){

return function(items, name){

    var arrayToReturn = [];        
    for (var i=0; i<items.length; i++){
        if (items[i].name != name) {
            arrayToReturn.push(items[i]);
        }
    }

    return arrayToReturn;
};

Вот рабочий jsFiddle: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

Другой простой альтернативой без написания пользовательских фильтров является сохранение имени для фильтрации в области видимости, а затем запись:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};
pkozlowski.opensource
источник
Спасибо! Сохранение имени в области не будет работать так хорошо, так как у меня есть три списка из одних и тех же данных на одной и той же странице при фильтрации с разными состояниями (или именами).
shapehifter
any, чтобы динамически установить «Адам» (относится к вашему JSFiddle)? кажется невозможным (и я предполагаю, что это специально) объединить ngModel и настраиваемый фильтр в Angular ...
Рольф
Можно ли изменить порядок параметров фильтра? Например, передать элемент второму параметру фильтра?
Pooya
Стоит отметить, что в этом примере разметка {{items | weDontLike: 'thenameyoudontlike'}} ... прямо сейчас вам нужно перейти к скрипке, чтобы получить это. Также стоит отметить, что вы можете передать несколько параметров своему пользовательскому фильтру {{items | weDontLike: 'thename': ['I am', 'an array']: 'и так далее'}} вы просто добавляете дополнительные аргументы в свой настраиваемый фильтр, чтобы иметь к ним доступ.
Бенджамин Конант,
62

На самом деле вы можете передать параметр ( http://docs.angularjs.org/api/ng.filter:filter ) и не нуждаетесь в специальной функции только для этого. Если вы перепишете свой HTML, как показано ниже, он будет работать:

<div ng:app>
 <div ng-controller="HelloCntl">
 <ul>
    <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
        <span>{{friend.name}}</span>
        <span>{{friend.phone}}</span>
    </li>
 </ul>
 </div>
</div>

http://jsfiddle.net/ZfGx4/59/

Микель
источник
8
Да. Примечание: если кого-то зовут '! Адам', вы получите его как {name: '!! Adam'}.
honzajde
5
Вы также можете передавать здесь массивы, вот такfilter:['Adam', 'john']
iConnor
6
ссылка jsfiddle не работает.
Seregwethrin
4
! Адам - ​​худшее имя на свете
Бен Уиллер,
6
«Не-Не-Адам» явно хуже.
twip
30

Вы можете просто сделать это в шаблоне

<span ng-cloak>{{amount |firstFiler:'firstArgument':'secondArgument' }}</span>

В фильтре

angular.module("app")
.filter("firstFiler",function(){

    console.log("filter loads");
    return function(items, firstArgument,secondArgument){
        console.log("item is ",items); // it is value upon which you have to filter
        console.log("firstArgument is ",firstArgument);
        console.log("secondArgument ",secondArgument);

        return "hello";
    }
    });
Абхайгарг12493
источник
Это лучший ответ. Работает с динамическими объектами. Это должен быть принятый ответ.
abelabbesnabi
2

Расширение ответа pkozlowski.opensource и использование array'sвстроенного метода фильтрации javascript может быть следующим:

.filter('weDontLike', function(){
    return function(items, name){
        return items.filter(function(item) {
            return item.name != name;
        });
    };
});

Вот ссылка на jsfiddle .

Подробнее о фильтре массива здесь .

Nasif Md. Tanjim
источник
1

Вы можете передать несколько аргументов угловому фильтру!

Определение моего приложения angular и переменной уровня приложения -

var app = angular.module('filterApp',[]);
app.value('test_obj', {'TEST' : 'test be check se'});

Ваш фильтр будет выглядеть так: -

app.filter('testFilter', [ 'test_obj', function(test_obj) {
    function test_filter_function(key, dynamic_data) {
      if(dynamic_data){
        var temp = test_obj[key]; 
        for(var property in dynamic_data){
            temp = temp.replace(property, dynamic_data[property]);
        }
        return temp;
      }
      else{
        return test_obj[key] || key;
      }

    }
    test_filter_function.$stateful = true;
    return test_filter_function;
  }]);

А из HTML вы отправите такие данные, как: -

<span ng-bind="'TEST' | testFilter: { 'be': val, 'se': value2 }"></span>

Здесь я отправляю в фильтр объект JSON. Вы также можете отправлять любые данные, такие как строка или число.

также вы можете передать динамическое количество аргументов для фильтрации, в этом случае вам нужно использовать аргументы для получения этих аргументов.

Для рабочей демонстрации перейдите сюда - передача нескольких аргументов в фильтр angular

Парта Рой
источник
0

Вы можете просто использовать | filter:yourFunction:arg

<div ng-repeat="group in groups | filter:weDontLike:group">...</div>

И в js

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
user2972221
источник