Пользовательский фильтр 'filter' в Angularjs - PullRequest
0 голосов
/ 17 мая 2018

У меня есть массив json, который содержит номер месяца и года. Я повторяю этот массив в шаблоне и отображаю месяц и год. Я использую пользовательский фильтр 'monthName' для преобразования номера месяца в названия месяцев. Теперь я хочу отфильтровать отображаемый список названий месяцев и года на основе пользовательского ввода. Невозможно использовать встроенный угловой фильтр js для массива, так как он содержит номер месяца, а не имена.

Вот фрагменты кода

JS

$scope.monthYr = [{month:"1", year: "2014"},{month:"2", year: "2015"},{month:"3", year: "2016"}

//custom filter to convert month number to month names
    app.filter('monthName', [function() {
        return function (monthNumber) { 
            var monthNames = [ 'January', 'February', 'March','April', 'May', 'June','July', 'August', 'September','October','November', 'December' ];
        return monthNames[monthNumber - 1];
    }

HTML

<div ng-repeat="item in monthYr ">
{{item.month | monthName}} &nbsp;({{item.year}})
</div>

Таким образом, отображаемый список выглядит следующим образом -

January (2014)
February (2015)
March (2016)

Возможные случаи совпадения с «март (2016)» - это когда пользователь вводит «март» или «2016» или «март (2016)». Так возможно ли в Angularjs создать собственный фильтр или вызвать функцию фильтра для получения ожидаемого результата?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

В том же контроллере, который вы определили $scope.monthYr, введите angularJs $filter и выполните следующие действия:

$scope.filterMounthYr = function() {
  // $scope.search is the input value
  $scope.monthYr = $filter('filter')($scope.monthYr, $scope.search);
}

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

Проверьте это Codepen

Обновление

Поскольку вы прокомментировали месяцы в списке, это числа, но входное значение - String.Поэтому я думаю, что вы должны пойти на JS встроенный метод filter.

$scope.filteredMonthYr = $scope.monthYr
$scope.filterMonthYr = function() {
  var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November', 'December'
  ];

  // Trim the serached word
  var search = $scope.search.trim()

  // Check if the month list contains
  if (monthNames.includes(search)) {
    $scope.searchKey = String(monthNames.indexOf(search) + 1);
  } else {
    $scope.searchKey = search;
  }
  // Only return if one of the contditions stated is true
  $scope.filteredMonthYr = $scope.monthYr.filter(function(o) {
    return (o["month"] == $scope.searchKey) ||
      (o["year"] == $scope.searchKey) || ($scope.searchKey in o)
  })
}

Полный код.

angular
  .module('MonthYearApp', [])
  .controller("MonthYearController", function MonthYearController($scope) {

    $scope.monthYr = [{
      month: "1",
      year: "2014"
    }, {
      month: "2",
      year: "2015"
    }, {
      month: "3",
      year: "2016"
    }, {
      month: "4",
      year: "2016"
    }, {
      month: "5",
      year: "2016"
    }, {
      month: "6",
      year: "2016"
    }]

    $scope.filteredMonthYr = $scope.monthYr
    $scope.filterMonthYr = function() {
      var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December'
      ];

      // Trim the serached word
      var search = $scope.search.trim()

      // Check if the month list contains
      if (monthNames.includes(search)) {
        $scope.searchKey = String(monthNames.indexOf(search) + 1);
      } else {
        $scope.searchKey = search;
      }
      // Only return if one of the conditions is true
      $scope.filteredMonthYr = $scope.monthYr.filter(function(o) {
        return (o["month"] == $scope.searchKey) ||
          (o["year"] == $scope.searchKey) || ($scope.searchKey in o)
      })
    }
  }).filter('monthName', [function() {
    return function(monthNumber) {
      var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December'
      ];
      return monthNames[monthNumber - 1];
    }
  }])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
<div ng-app="MonthYearApp">
  <div ng-controller="MonthYearController">
    <input type='text' data-ng-model='search'>
    <button ng-click='filterMonthYr()'>Filter</button>
    <table>
      <tr data-ng-repeat="item in filteredMonthYr">
        <td> {{item.month | monthName}} </td>
        <td>{{item.year}}</td>
      </tr>
    </table>
  </div>
</div>

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


Обновление

Использование ng-change и оператора if-else внутри функции filterMonthYr.

angular
  .module('MonthYearApp', [])
  .controller("MonthYearController", function MonthYearController($scope) {

    $scope.monthYr = [{
      month: "1",
      year: "2014"
    }, {
      month: "2",
      year: "2015"
    }, {
      month: "3",
      year: "2016"
    }, {
      month: "4",
      year: "2016"
    }, {
      month: "5",
      year: "2016"
    }, {
      month: "6",
      year: "2016"
    }]

    $scope.filteredMonthYr = $scope.monthYr
    $scope.filterMonthYr = function() {
      var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December'
      ];

      // Trim the serached word
      var search = $scope.search.trim()

      // Check if the month list contains
      if (monthNames.includes(search)) {
        $scope.searchKey = String(monthNames.indexOf(search) + 1);
      } else {
        $scope.searchKey = search;
      }
      // Only return if one of the conditions is true
      var monthYr = $scope.monthYr.filter(function(o) {
        return (o["month"] == $scope.searchKey) ||
          (o["year"] == $scope.searchKey) || ($scope.searchKey in o)
      })

      if (monthYr.length > 0) {
        $scope.filteredMonthYr = monthYr
      } else {
        $scope.filteredMonthYr = $scope.monthYr
      }
    }
  }).filter('monthName', [function() {
    return function(monthNumber) {
      var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December'
      ];
      return monthNames[monthNumber - 1];
    }
  }])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
<div ng-app="MonthYearApp">
  <div ng-controller="MonthYearController">
    <input type='text' data-ng-model='search' ng-change="filterMonthYr()">
    <button ng-click=''>Filter</button>
    <table>
      <tr data-ng-repeat="item in filteredMonthYr">
        <td> {{item.month | monthName}} </td>
        <td>{{item.year}}</td>
      </tr>
    </table>
  </div>
</div>
0 голосов
/ 17 мая 2018

Вы должны использовать регулярное выражение для проверки каждого элемента в массиве, если оно соответствует вашему условию, а вот выражение /(\[)?March(2016)?.*(\])?.[0-9]{4}/ чтобы проверить, скопируйте и вставьте этот код в веб-консоль для просмотра результата: /(\[)?March(2016)?.*(\])?.[0-9]{4}/.test('(March 2016)') и измените параметр test(). и в зависимости от test () возвращаемое логическое значение будет фильтровать массив

...