Фильтрация AngularJS между диапазоном

Я установил ползунок диапазона в диапазоне от 0 до 2 часов, время рассчитывается в минутах, а затем преобразуется в чч: мм следующим образом: 10 минут, 20 минут, 1 час 20 минут, 2 часа.

Но теперь я пытаюсь отфильтровать кучу элементов внутри ng-repeat, используя диапазон, указанный ползунком диапазона, и мне трудно заставить это работать.

Вот что я сделал http://cdpn.io/LDusa

Я использую http://danielcrisp.github.io/angular-rangeslider/demo/ для ползунка диапазона.

А вот код:

var app = angular.module('myApp', ['ui-rangeSlider']);
app.controller('myCtrl', function ($scope) {
    $scope.sliderConfig = {
        min:  0,
        max:  120,
        step: 10,
        userMin: 0,
        userMax: 30
    };

   $scope.times = [
      {"time": "20"},
      {"time": "50"},
      {"time": "30"},
      {"time": "10"},
      {"time": "85"},
      {"time": "75"},
      {"time": "95"},
      {"time": "100"},
      {"time": "80"},
      {"time": "200"},
      {"time": "260"},
      {"time": "120"},
      {"time": "62"},
      {"time": "68"},
      {"time": "5"},
      {"time": "116"}
   ];
});

app.filter('customFilter', function () {
    return function (value) {
        var h = parseInt(value / 60);
        var m = parseInt(value % 60);

        var hStr = (h > 0) ? h + 'hr'  : '';
        var mStr = (m > 0) ? m + 'min' : '';
        var glue = (hStr && mStr) ? ' ' : '';

        return hStr + glue + mStr;
    };
});

app.filter('range', function() {
  return function(input, min, max) {
    min = parseInt(min);
    max = parseInt(max);
    for (var i=min; i<=max; i++)
      input.push(i);
    return input;
  };
});

JADE (если вы предпочитаете HTML, вы можете преобразовать его обратно в html, используя этот http://html2jade.org/):

div(ng-app="myApp")
  div(ng-controller='myCtrl')
    div(range-slider='', pin-handle='min', attach-handle-values='', prevent-equal-min-max='', step='{{sliderConfig.step}}', min='sliderConfig.min', max='sliderConfig.max', model-min='sliderConfig.userMin', model-max='sliderConfig.userMax', filter='customFilter')


    div(range-slider, prevent-equal-min-max='', attach-handle-values='',  min='sliderConfig.min', max='sliderConfig.max', model-min='sliderConfig.userMin', model-max='sliderConfig.userMax', filter='customFilter')

    div(ng-repeat="time in times | range:sliderConfig.userMin:sliderConfig.userMax")
      | {{ item.time | customFilter }}

Как я могу заставить это работать, чтобы отображать элементы только тогда, когда time находится в пределах диапазона, указанного в ползунке диапазона?


person Daimz    schedule 19.05.2014    source источник
comment
Вы можете обернуть свои элементы ng-show в сочетании с условием диапазона. Я изменил ваш пример, чтобы продемонстрировать, что я имею в виду - codepen.io/anon/pen/ApvcF   -  person miqh    schedule 19.05.2014


Ответы (1)


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

    <div range-slider="range-slider" 
         min="sliderConfig.min" 
         max="sliderConfig.max" 
         model-min="sliderConfig.userMin" 
         model-max="sliderConfig.userMax">
    </div>
    ...
    // Pass the slider config into the filter
    <div ng-repeat="time in times | rangeFilter:sliderConfig">
        {{ time.time | customFilter}}
    </div>
    ...
    $scope.times = [
      {time: '20'},
      {time: '50'},
      ...
    ];

RangeFilter имеет второй параметр rangeInfo, из которого мы можем получить 2 значения.

app.filter('rangeFilter', function() {
    return function( items, rangeInfo ) {
        var filtered = [];
        var min = parseInt(rangeInfo.userMin);
        var max = parseInt(rangeInfo.userMax);
        // If time is with the range
        angular.forEach(items, function(item) {
            if( item.time >= min && item.time <= max ) {
                filtered.push(item);
            }
        });
        return filtered;
    };
});

Надеюсь, поможет.

person Digital Fu    schedule 19.05.2014
comment
Это работает отлично, у меня только один вопрос. Можно ли заставить эту работу работать с несколькими ползунками диапазона. Я пытался добиться этого cdpn.io/LDusa, но не знаю, как настроить фильтр на ng-repeat теперь, когда он вызывает sliderConfig в rangeFilter. Я думаю, мне нужно было бы как-то использовать secondTimeConfig с SliderConfig, но я не уверен. - person Daimz; 19.05.2014
comment
Я добавил дополнительную информацию к ответу - person Digital Fu; 19.05.2014
comment
С двумя ползунками диапазона идея состоит в том, что если я начну фильтровать время в диапазоне от 20 минут до 1 часа 20 минут, то я использую ползунок второго диапазона, чтобы найти элементы в этом диапазоне от 20 минут до 1 часа 20 минут, которые имеют значение «secondTime» между 10 минутами и 100 минутами. Я не хочу перезаписывать первый ползунок, когда использую второй, я бы хотел, чтобы они оба могли фильтровать информацию относительно друг друга. Похоже, вы проверяете, отличаются ли maxOne и maxTwo, а затем фильтруете на основе этого. И я не уверен, что это будет работать так, как я хочу. Пожалуйста, поправьте меня, если я ошибаюсь, так как я хотел бы научиться. - person Daimz; 19.05.2014
comment
Пробовал это, но я не мог заставить его работать. cdpn.io/LDusa Я также перешел с JADE на HTML, вдруг вам будет проще. - person Daimz; 19.05.2014
comment
Возможно, это может прояснить ситуацию, я установил плункер embed.plnkr.co/jHtvnHxnmb5s6V36rJJY/preview Я добавил в код комментарий о том, что, похоже, нарушает работу фильтра. Но, надеюсь, это просто прояснит, чего я пытаюсь достичь. - person Daimz; 19.05.2014
comment
Теперь это имеет гораздо больше смысла. plnkr.co/edit/j5nrgw8vD0NepvvzJcyO?p=preview - person Digital Fu; 20.05.2014
comment
Спасибо, это имеет смысл и работает очень хорошо. Благодарим за помощь - person Daimz; 20.05.2014