Объединение rangeSlider с поисковым фильтром в AngularJS

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

//Person view:
//rangeSlider
<div class="form-group form-group-sm">
   <label class="col-sm-3 control-label">Age:</label>
   <div class="col-sm-8">
     <div range-slider min="0" max="100" model-min="demo.min" model-max="search.age" pin-handle="min" show-values="true" ng-model="search.age">
     </div>
   </div>
</div>
...
//table list with items
<tr ng-repeat="person in personslist | filter:search">
    <td>{{ person.id }}</td>
    <td>{{ person.fname }}</td>
    <td>{{ person.age }}</td>
</tr>
...

//PersonCtrl
$scope.demo = {
  max: 100,
  min: 0
};

Я думаю, что ngModel в директиве rangeSlider не получает значение search.age. В атрибуте model-max я также добавил search.age. Когда я ищу максимальное число 8 в своей форме поиска, она отображает людей в возрасте 8, 18, 38 и так далее. Но результат должен быть 0-8. Как я могу это решить? Я также пытался определить функцию в атрибуте on-handle-up, но я не знаю, как получить элемент в filter: search.


person yuro    schedule 29.05.2015    source источник


Ответы (1)


Я думаю, проблема в том, что вы используете filter. Он основан на тексте, поэтому ваши результаты фильтруются по результатам, содержащим символ «8» в их возрасте.

Вместо этого создайте собственный фильтр, который делает то, что вы хотите. Приведенный ниже фильтр ограничит результаты по возрастному диапазону:

App.filter('range', function() {
    return function(list, min, max) {
        max = parseInt(max);
        var result = [];
        angular.forEach(list, function(input) {
            if (input.age >= min && input.age <= max) result.push(input);
        });
        return result;
    };
});

Затем вы можете использовать значение search.age в качестве максимального аргумента и 0 в качестве минимального аргумента, чтобы вернуть все результаты между нулем и значением ползунка возраста:

<tr ng-repeat="person in personslist | range:0:search.age">

Изменив ползунок диапазона, вы можете использовать как минимальное, так и максимальное значения диапазона из ползунка. Согласно вашим комментариям ниже, объект «$scope.search» не может содержать значения диапазона, поскольку они также будут выбраны filter, я использовал отдельную переменную области видимости, называемую «$scope.ranges»:

<div range-slider model-min="ranges.min_age" model-max="ranges.max_age" ...></div>

<tr ng-repeat="person in personslist | range:ranges.min_age:ranges.max_age | filter:search">

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

Вот пример: http://jsfiddle.net/g0woejpf/2/

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

person seanhodges    schedule 29.05.2015
comment
Это хорошее решение, но фильтр должен определять и другие поля ввода поиска, содержащие строки. - person yuro; 29.05.2015
comment
Это должно быть достаточно просто, просто соедините фильтры... person in personslist | range:search.min_age:search.max_age | filter:search - просто убедитесь, что вы не назначаете search.age, так как это снова вызовет текстовый поиск в поле возраста! - person seanhodges; 29.05.2015
comment
Я пробовал это определение, но оно дает мне не элементы. Работает только rangeSlider. - person yuro; 29.05.2015
comment
Я собрал пример. Кажется, что значения search.min_age / search.max_age сбивали с толку filter, поэтому вам нужно будет разместить эти свойства в другом месте, чтобы все заработало. - person seanhodges; 29.05.2015
comment
хорошо..Теперь работает :) .. У меня еще один вопрос. Когда я нажимаю на другое поле ввода, другие 2 отключаются, а ввод, который вы написали, удаляется. Это работает, но rangeSlider остается тем же значением. Я хочу, чтобы если rangeSlider отключен, значение снова было равно 100. Как я могу это исправить? - person yuro; 29.05.2015
comment
Либо установите $scope.ranges.max_age на 100 при отключении ползунка, либо передайте объект поиска в фильтр range и верните весь список, если присутствуют какие-либо другие значения поиска. - person seanhodges; 29.05.2015