AngularJS多重过滤器

时间:2017-04-06 21:47:45

标签: javascript angularjs

我有一个订单列表和一个下拉列表,可根据状态过滤订单。状态包括:未交付,未完全交付和部分交付。过滤在这3个选项中运行良好,但是我想实现一个额外的选项,同时显示未交付和部分交付的订单。

<select class="form-control" id="status" ng-model="orderFilter.status"
        ng-init="orderFilter.status = '_'">
    <option value="_">all</option>
    <option value="_not" class="text-danger">not delivered</option>
    <option value="_part" class="text-info">partially delivered</option>
    <option value="n-p" class="text-warning">not and partial</option>
    <option value="_done" class="text-success">delivered</option>
</select>

所以我添加了一个新的&#34; custom&#34;价值,以及它所有工作的方式,它是复制一个或另一个的对象,这是坏的,多余的,而不是我想要的。

我认为可能有类似的事情:

<option value="_not || _part" class="text-warning">not and partial</option>

过滤部分:

<tr ng-repeat="s in vm.sales | filter: orderFilter">
    <td>...</td>
</tr>

2 个答案:

答案 0 :(得分:1)

最好的解决方案是编写自己的过滤器,如果您出于某种原因不想这样做,那么您可以根据所选值过滤程序列表并更新列表:

<select class="form-control" ng-change="filterSales()" id="status" ng-model="orderFilter.status"
    ng-init="orderFilter.status = '_'">
    <option value="_">all</option>
    <option value="_not" class="text-danger">not delivered</option>
    <option value="_part" class="text-info">partially delivered</option>
    <option value="n-p" class="text-warning">not and partial</option>
    <option value="_done" class="text-success">delivered</option>
</select>

而不是在你的控制器某处:

$scope.filterSales = function(){
   if($scope.orderFilter.status === 'n-p'){
      var filteredWithNoStatus = $filter('filter')($scope.vm.sales,'_not');
      var filteredWithPartStatus = $filter('filter')($scope.vm.sales,'_part');
      $scope.filteredList =  Object.assign(filteredWithNoStatus,filteredWithPartStatus);
   }else{
       $scope.filteredList = $filter('filter')($scope.vm.sales,$scope.orderFilter.status);
   }
}

在您的html中,您可以删除过滤器

<tr ng-repeat="s in filteredList>
   <td>...</td>
</tr>

很抱歉我没有时间测试代码,但我希望你理解这个想法。

答案 1 :(得分:0)

如果您的可能状态不会发生变化,您可以使用!_done作为选项值,该值会过滤掉_done,但会离开_not_part

var app = angular.module("app", []);

app.controller("controller", function($scope) {
  $scope.orderFilter = {
    status: "_"
  };

  $scope.sales = [{
      status: "_not",
      item: "NOT"
    },
    {
      status: "_part",
      item: "PART"
    },
    {
      status: "_done",
      item: "DONE"
    }
  ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
  <select class="form-control" id="status" ng-model="orderFilter.status">
    <option value="_">all</option>
    <option value="_not" class="text-danger">not delivered</option>
    <option value="_part" class="text-info">partially delivered</option>
    <option value="!_done" class="text-warning">not and partial</option>
    <option value="_done" class="text-success">delivered</option>
  </select> {{orderFilter}}

  <table>
    <tbody>
      <tr ng-repeat="s in sales | filter: orderFilter.status">
        <td>{{s.item}}</td>
      </tr>
    </tbody>
  </table>
</div>

否则您需要编写自定义过滤器。请参阅下面的代码段,您可以添加多个值,例如"_not, _part"会返回未部分投放的项目。

var app = angular.module("app", []);

app.controller("controller", function($scope) {
  $scope.orderFilter = {
    status: ""
  };

  $scope.sales = [{
      status: "_not",
      item: "NOT"
    },
    {
      status: "_part",
      item: "PART"
    },
    {
      status: "_done",
      item: "DONE"
    }
  ];
});

app.filter("filterByProp", function() {
  return function(items, prop, filterVal) {
    // don't filter if no value to filter on
    if (!filterVal) {
      return items;
    }
    
    // split filter val to allow for multiple props e.g. "_not, _part"
    var filters = filterVal.replace(" ", "").split(",");
    
    // only return items which match at least one of the values
    return items.filter(function(item) { 
      return filters.indexOf(item[prop]) > -1 
    });
  };
});;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
  <select class="form-control" id="status" ng-model="orderFilter.status">
    <option value="">all</option>
    <option value="_not" class="text-danger">not delivered</option>
    <option value="_part" class="text-info">partially delivered</option>
    <option value="_not, _part" class="text-warning">not and partial</option>
    <option value="_done" class="text-success">delivered</option>
  </select> {{orderFilter}}

  <table>
    <tbody>
      <tr ng-repeat="s in sales | filterByProp : 'status' : orderFilter.status">
        <td>{{s.item}}</td>
      </tr>
    </tbody>
  </table>
</div>