Как использовать фильтр в контроллере?

649

Я написал функцию фильтра, которая будет возвращать данные на основе аргумента, который вы передаете. Я хочу такую ​​же функциональность в моем контроллере. Можно ли повторно использовать функцию фильтра в контроллере?

Это то, что я пробовал до сих пор:

function myCtrl($scope,filter1)
{ 
    // i simply used the filter function name, it is not working.
}
Самант
источник
2
лучший ответ: stackoverflow.com/questions/20131553/…
Раза Ахмед

Ответы:

1051

Введите $ фильтр на ваш контроллер

function myCtrl($scope, $filter)
{
}

Тогда везде, где вы хотите использовать этот фильтр, просто используйте его так:

$filter('filtername');

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

function myCtrl($scope, $filter)
{
    $filter('filtername')(arg1,arg2);
}

Где arg1находится массив, по которому вы хотите фильтровать, и arg2объект, используемый для фильтрации.

JSAddict
источник
21
Извините, сэр, я до сих пор не понимаю. Не могли бы вы сделать Jsfiddle, чтобы показать, как определить тело функции фильтра и как она вставляется в HTML-файл?
gm2008
34
@ gm2008 вы можете использовать числовой фильтр, как var anyNumber = $filter('number')(12.222222, 2);получить 12.22.
Винеш
20
+ Я за ответ на вопрос ... который был "Как использовать фильтр в контроллере?"
Shanimal
8
Пример со встроенным фильтром «валюта»: $filter("currency")(price, "$", 2)так что если бы у вас была цена = 200, то это выражение вернуло бы «200,00 $».
Netsi1964
2
Ответ @ pkozlowski.opensource лучше, чем этот, потому что он уменьшает «волшебные строки». Одно из преимуществ - что если это был гораздо более сложный контроллер, и вам не удалось провести модульное тестирование используемого фильтра? Вы не заметите ошибку, если будете использовать $filter('filtter1')(2 т). Однако, если вы введете filtter1FilterAngular, вы сразу же пожалуетесь, что зависимость не существует.
jkjustjoshing
253

Ответ, предоставленный @Prashanth, является правильным, но есть еще более простой способ сделать то же самое. По сути, вместо внедрения $filterзависимости и использования неудобного синтаксиса вызова it ( $filter('filtername')(arg1,arg2);) можно ввести зависимость: имя фильтра плюс Filterсуффикс.

Взяв пример из вопроса, можно написать:

function myCtrl($scope, filter1Filter) { 
  filter1Filter(input, arg1);
}

Следует отметить, что вы должны добавить Filterк имени фильтра, независимо от того, какое соглашение об именах вы используете: на foo ссылается вызов fooFilter
fooFilter, на который ссылается вызовfooFilterFilter

pkozlowski.opensource
источник
38
Конечно ... но я все еще нахожу вариант использования, в котором вы хотели бы внедрить 10 фильтров в один класс ... Такой класс, вероятно, нарушил бы принцип единой ответственности ...
pkozlowski.opensource
10
Просто чтобы прояснить, что это не «неуклюжий» синтаксис JS… var fooFilter = $ filter ('foo'); fooFilter (arg1, arg2);
вслепую
13
@OZ_ что ты имеешь в виду? Работает минификация или нет. Минификация не имеет здесь никакого отношения, посмотрите этот план
pkozlowski.opensource
2
Это идеально подходит для использования одного фильтра, который я встретил.
Мэтью Fotzler
2
+1 Я думаю, что синтаксис $ filter скрывает зависимости, что приводит к снижению удобства сопровождения кода. Инъекция фильтров «статически» - лучший выбор.
BiAiB
79

Используя следующий пример кода, мы можем фильтровать массив в угловом контроллере по имени. это основано на следующем описании. http://docs.angularjs.org/guide/filter

this.filteredArray = filterFilter (this.array, {name: 'Igor'});

JS:

 angular.module('FilterInControllerModule', []).
    controller('FilterController', ['filterFilter', function(filterFilter) {
      this.array = [
        {name: 'Tobias'},
        {name: 'Jeff'},
        {name: 'Brian'},
        {name: 'Igor'},
        {name: 'James'},
        {name: 'Brad'}
      ];
      this.filteredArray = filterFilter(this.array, {name:'Igor'});
    }]);

HTML

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-example96-production</title>


  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.3/angular.min.js"></script>
  <script src="script.js"></script>



</head>
<body ng-app="FilterInControllerModule">
    <div ng-controller="FilterController as ctrl">
    <div>
      All entries:
      <span ng-repeat="entry in ctrl.array">{{entry.name}} </span>
    </div>
    <div>
      Filter By Name in angular controller
      <span ng-repeat="entry in ctrl.filteredArray">{{entry.name}} </span>
    </div>
  </div>
</body>
</html>
Аамир Саджад
источник
4
filterFilter (this.array, {name: 'Igor'}); является ли filterFilter ключевым словом или каким оно автоматически отфильтровывает данные и почему ['filterFilter', function (filterFilter) {определено здесь! ?
Сурадж Рават
Plnkr с большим количеством примеров этой техники: plnkr.co/edit/icFurX?p=preview
OzBob
Очень полезно. Спасибо.
Кушал Джейсвал
48

Вот еще один пример использования filterв контроллере Angular:

$scope.ListOfPeople = [
    { PersonID: 10, FirstName: "John", LastName: "Smith", Sex: "Male" },
    { PersonID: 11, FirstName: "James", LastName: "Last", Sex: "Male" },
    { PersonID: 12, FirstName: "Mary", LastName: "Heart", Sex: "Female" },
    { PersonID: 13, FirstName: "Sandra", LastName: "Goldsmith", Sex: "Female" },
    { PersonID: 14, FirstName: "Shaun", LastName: "Sheep", Sex: "Male" },
    { PersonID: 15, FirstName: "Nicola", LastName: "Smith", Sex: "Male" }
];

$scope.ListOfWomen = $scope.ListOfPeople.filter(function (person) {
    return (person.Sex == "Female");
});

//  This will display "There are 2 women in our list."
prompt("", "There are " + $scope.ListOfWomen.length + " women in our list.");

Просто, эй?

Майк Гледхилл
источник
6
Это именно то, что мне было нужно, спасибо. Хотя, видимо, вопрос не в этом. :)
pvgoran
38

Есть три возможных способа сделать это.

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

app.filter('uppercase', function() {
    return function(string, firstCharOnly) {
        return (!firstCharOnly)
            ? string.toUpperCase()
            : string.charAt(0).toUpperCase() + string.slice(1);
    }
});

Прямо через $filter

app.controller('MyController', function($filter) {

    // HELLO
    var text = $filter('uppercase')('hello');

    // Hello
    var text = $filter('uppercase')('hello', true);

});

Примечание: это дает вам доступ ко всем вашим фильтрам.


Присвоить $filterк аvariable

Эта опция позволяет вам использовать $filterкак function.

app.controller('MyController', function($filter) {

    var uppercaseFilter = $filter('uppercase');

    // HELLO
    var text = uppercaseFilter('hello');

    // Hello
    var text = uppercaseFilter('hello', true);

});

Загрузить только определенный Filter

Вы можете загрузить только определенный фильтр, добавив имя фильтра с помощью Filter.

app.controller('MyController', function(uppercaseFilter) {

    // HELLO
    var text = uppercaseFilter('hello');

    // Hello
    var text = uppercaseFilter('hello', true);

});

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

Джеффри Розендал
источник
15
function ngController($scope,$filter){
    $scope.name = "aaaa";
    $scope.age = "32";

     $scope.result = function(){
        return $filter('lowercase')($scope.name);
    };
}

Имя второго аргумента метода контроллера должно быть «$ filter», тогда только функции фильтра будут работать с этим примером. В этом примере я использовал «строчный» фильтр.

ИПАГ
источник
12

У меня есть еще один пример, который я сделал для своего процесса:

Я получаю массив со значением-описание, как это

states = [{
    status: '1',
    desc: '\u2713'
}, {
    status: '2',
    desc: '\u271B'
}]

в моем Filters.js:

.filter('getState', function () {
    return function (input, states) {
        //console.log(states);
        for (var i = 0; i < states.length; i++) {
            //console.log(states[i]);
            if (states[i].status == input) {
                return states[i].desc;
            }
        }
        return '\u2718';
    };
})

Затем тестовый var (контроллер):

function myCtrl($scope, $filter) {
    // ....
    var resp = $filter('getState')('1', states);
    // ....
}
NtSpeed
источник
Будет ли это работать в angularjs 1.0.8? потому что это не работает для меня .. говорит, что фильтр $ не определен даже после того, как я добавил это в контроллере
shajin
7

AngularJs позволяет использовать фильтры внутри шаблона или внутри контроллера, директивы и т. Д.

в шаблоне вы можете использовать этот синтаксис

{{ variable | MyFilter: ... : ... }}

и внутри контроллера вы можете использовать внедрение службы $ filter

angular.module('MyModule').controller('MyCtrl',function($scope, $filter){
    $filter('MyFilter')(arg1, arg2);
})

Если вам нужно больше с примером Демо здесь ссылка

AngularJs примеры фильтров и демо

Азарапет Туанян
источник
Inceting это не слово. Вы имеете в виду инъекцию?
Кевинк
oops.yea Я имею в виду инъекцию.
Хазарапет Тунанян
6

Есть еще один способ оценки фильтров, который отражает синтаксис из представлений. Это волосатый вызов, но вы можете создать для него ярлык. Мне нравится, что синтаксис строки идентичен тому, что вы имели бы в представлении. Выглядит так:

function myCtrl($scope, $interpolate) { 
  $scope.$eval($interpolate( "{{ myvar * 10 | currency }} dollars." ))
}
SimplGy
источник
Это на самом деле очень полезно!
DragonKnight
1
это фантастика, так как позволяет передать строку, которая выглядит так же, как в разметке.
Кевинк
5

Кажется, никто не упомянул, что вы можете использовать функцию как arg2 в $ filter ('filtername') (arg1, arg2);

Например:

$scope.filteredItems = $filter('filter')(items, function(item){return item.Price>50;});
pavok
источник
2

Простой пример даты с использованием $ filter в контроллере:

var myDate = new Date();
$scope.dateAsString = $filter('date')(myDate, "yyyy-MM-dd"); 

Как объяснено здесь - https://stackoverflow.com/a/20131782/262140

AVH
источник
1

Используйте код ниже, если мы хотим добавить несколько условий вместо одного значения в угловом фильтре javascript:

var modifiedArray = $filter('filter')(array,function(item){return (item.ColumnName == 'Value1' || item.ColumnName == 'Value2');},true)
Амай Кулкарни
источник
1

Прежде всего, вставьте $ filter в ваш контроллер, убедившись, что ngSanitize загружен в ваше приложение, а позже при использовании контроллера вы увидите следующее:

$filter('linky')(text, target, attributes)

Всегда проверяйте документы angularjs

serdarsenay
источник
1

если вы хотите отфильтровать объект в контроллере попробуйте это

var rateSelected = $filter('filter')($scope.GradeList, function (obj) {
                        if(obj.GradeId == $scope.contractor_emp.save_modal_data.GradeId)
                        return obj;
                });

Это вернет отфильтрованный объект в соответствии с условием if

Код Шпион
источник
0

Повторное использование фильтра Angular.js - представление / контроллер

Это решение охватывает повторное использование угловых фильтров. Это еще один способ фильтрации данных, и Google высадил меня здесь, когда мне это было нужно; и я хотел бы поделиться.

Случай использования

Если вы уже выполняете фильтрацию, скажем, в виде ng-repeat (как показано ниже), тогда вы могли бы определить фильтр в контроллере следующим образом. И тогда вы можете использовать повторно, как в последних примерах.

Пример использования фильтра - отфильтрованный повтор в представлении

<div ng-app="someApp" ng-controller="someController">
    <h2>Duplicates</h2>
    <table class="table table-striped table-light table-bordered-light">
        <thead>
            <tr>
                <th>Name</th>
                <th>Gender</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="person in data | filter: searchDuplicate:true">
                <td>{{person.name}}</td>
                <td>{{person.gender}}</td>
            </tr>
        </tbody>
    </table>
</div>

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

angular.module('someApp',[])
.controller('someController', function($scope, $filter ) {

    $scope.people = [{name: 'Bob', gender: 'male'  , hasDuplicate: true },
                     {name: 'Bob', gender: 'male'  , hasDuplicate: true },
                     {name: 'Bob', gender: 'female', hasDuplicate: false}];

    $scope.searchDuplicate = { hasDuplicate : true };
})

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

Использование функции фильтра в контроллере Пример 1

var dup = $filter('filter')($scope.people, $scope.searchDuplicate, true)

Использование функции фильтра в контроллере Пример 2

Показывать кнопку только в том случае, если дубликаты не найдены, используя предыдущий фильтр.

Кнопка HTML

<div ng-if="showButton()"><button class="btn btn-primary" ng-click="doSomething();"></button></div>

Показать / Скрыть кнопку

$scope.doSomething = function(){ /* ... */ };
$scope.showButton = function(){ return $filter('filter')($scope.people, $scope.searchDuplicate, true).length == 0; };

Некоторые могут найти эту версию фильтрации легкой, и это опция Angular.js.

Необязательный параметр компаратора «true», используемый в представлении и в вызове функции $ filter, указывает на необходимость строгого сравнения. Если вы пропустите, можно искать значения по нескольким столбцам.

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

Greg
источник