自定义过滤器'过滤器'在Angularjs

时间:2018-05-17 07:53:43

标签: angularjs angularjs-filter

我有一个包含月份数和年数的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)

所以可能的情况匹配&#39; March(2016)&#39;当用户输入&#39; March&#39;或者&#39; 2016&#39;或者&#39; March(2016)&#39;。那么在Angularjs中是否可以构建自定义过滤器过滤器或在过滤器上调用预期结果的函数?

2 个答案:

答案 0 :(得分:0)

在您定义$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-elsefilterMonthYr语句。

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>

答案 1 :(得分:-1)

如果符合条件,你应该使用正则表达式来测试数组中的每个元素,这里是表达式/(\[)?March(2016)?.*(\])?.[0-9]{4}/ 检查在Web控制台中复制并粘贴此代码以查看结果:/(\[)?March(2016)?.*(\])?.[0-9]{4}/.test('(March 2016)')并更改test()参数。 并且取决于test()返回的布尔值将过滤数组