Динамический фильтр в ng-repeat в AngularJS

Для моего приложения AngularJS у меня есть ng-repeat в ng-repeat, например:

HTML:

<div ng-app="myApp">
    <div ng-controller="myController">
        <h2>working filter</h2>
        <div ng-repeat="category in categories">
            <h3>{{category}}</h3>
            <div ng-repeat="item in items | filter:{price.red: 0} ">{{item.name}}</div>
    </div>

        <h2>broken filter</h2>
        <div ng-repeat="category in categories">
            <h3>{{category}}</h3>
            <!-- price[category] should be red, blue, yellow, depending on the category in the ng-repeat -->
            <!-- price[category] should be bigger then 0 (or not zero, negative values will not occur) -->
            <div ng-repeat="item in items | filter:{price[category]: 0} ">{{item.name}}</div>
        </div>

    </div>
</div>

Javascript:

var myApp = angular.module('myApp', []);

myApp.controller('myController', function ($scope) {

    $scope.categories = ['red', 'blue', 'yellow'];
    $scope.items = [
        {name: 'one', price:{red: 0, blue: 1, yellow: 3} },
        {name: 'two', price:{red: 2, blue: 0, yellow: 0}},
    ]    

});

Пожалуйста, посмотрите мой jsFiddle http://jsfiddle.net/hm8qD/

Итак, я столкнулся с двумя проблемами:

  1. Фильтр не принимает [] скобки, поэтому я не могу сделать фильтр динамическим в зависимости от категории.
  2. Фильтр должен возвращать товары, у которых цена[категория] больше нуля.

Для большего, чем ноль, я мог бы просто создать собственный фильтр. Однако, насколько мне известно, фильтры не принимают параметры, поэтому у меня нет возможности получить для него категорию (красный, синий или желтый).

Обратите внимание, что это упрощенная версия моего фактического кода, и этот контекст может иметь не лучший смысл. Надеюсь, я ясно объяснил, для чего мне нужен фильтр, так как я новичок в AngularJS.


person DivZero    schedule 17.05.2013    source источник
comment
Можете ли вы сбросить свою попытку в jsFiddle?   -  person Mathew Berg    schedule 17.05.2013
comment
синтаксис фильтра: item in items | filter:filterCriteria   -  person TheHippo    schedule 17.05.2013
comment
@MathewBerg Я добавил jsFiddle: jsfiddle.net/hm8qD   -  person DivZero    schedule 17.05.2013
comment
@itcouldevenbeaboat, пожалуйста :-) jsfiddle.net/hm8qD   -  person DivZero    schedule 17.05.2013


Ответы (2)


По-видимому, на самом деле можно передавать аргументы вашему фильтру, но вам нужно создать собственный фильтр вместо использования «фильтр: выражение». Что я сделал, так это создал собственный фильтр, который принимает элементы и категорию в качестве аргументов и возвращает массив с отфильтрованными элементами.

myApp.filter('myFilter', function () {
    return function (items, category) {
        var newItems = [];
        for (var i = 0; i < items.length; i++) {
            if (items[i].price[category] > 0) {
                newItems.push(items[i]);
            }
        };

        return newItems;
    }
});

См. обновленный Fiddle здесь: http://jsfiddle.net/hm8qD/3/

person DivZero    schedule 17.05.2013

Я нашел другое и довольно аккуратное решение для отправки параметров в фильтр (написано на es6):

$scope.myFilter = (category) => {
  return (item) => {
    if(category === 'fish' && item.type === 'salmon'){
       return true
    }
    return false
  }
}

разметка будет:

<div ng-repeat="item in items | 
filter:myFilter(someCategory)>
     {{item.name}}
</div>

Таким образом, вы можете просто указать «категорию» в фильтре, поскольку myFilter возвращает функцию в формате, ожидаемом фильтром.

person Fraction    schedule 09.09.2015