如何使用复选框在Angular中过滤结果?

4

我正在尝试使用复选框应用过滤器。

复选框显示正确:

<div data-ng-repeat="cust in customers">
    <input type="checkbox" data-ng-model="search.city" data-ng-true-value="{{ cust.city }}" data-ng-false-value=""/> {{ cust.city }}
</div>

但是当勾选任何复选框时,没有任何反应:
<table>

    <!-- table heading goes here -->

    <tbody>
        <tr data-ng-repeat="customer in customers | filter : search">
            <td >
                {{ customer.firstName }}
            </td>
            <td >
                {{ customer.lastName }}
            </td>
            <td >
                {{ customer.address }}
            </td>
            <td >
                {{ customer.city }}
            </td>
        </tr>
    </tbody>
</table>
显示所有客户。

我的目标是:当一个或多个复选框被选中时,表格必须仅显示符合所选复选框条件的行。

我需要做什么才能让它起作用?

2个回答

7
您可以将一个函数传递给AngularJS过滤器。例如:
将您的input标签设置为:
<input type="checkbox" ng-model="search[cust.city]" /> {{ cust.city }}

将您的筛选器设置为:

<tr data-ng-repeat="customer in customers | filter:searchBy() ">

在你的控制器中:

function ctrl($scope) {
  $scope.customers = [...];

  $scope.search = {};    
  $scope.searchBy = function () {
    return function (customer) {
      if ( $scope.search[customer.city] === true ) {
        return true;
      }
    }
  };
}

如果您希望在启动时显示所有客户,则可以通过从“customers”数组中获取“city”将$scope.search初始化。
这里是一个示例Plunker: 链接

我更喜欢这个答案,而且它似乎也会更快。 - fauverism
1
如果您希望在启动时显示所有客户,只需使用来自客户数组的城市初始化$scope.search即可。您需要更详细地解释一下吗?是否需要示例? - Neeraj Sharma
如果两个或更多客户属于同一个城市,则此解决方案不会对复选框进行分组。 - llermaly

3

看起来你正在提供客户列表,当选择一个或多个客户时,显示与那些选择的客户在同一城市的客户表。

为了实现这个功能,你需要一个自定义过滤器:

// Define our filter
app.filter('selectedCustomerCities', function($filter) {
  return function(customers) {
    var i, len;

    // get customers that have been checked
    var checkedCustomers = $filter('filter')(customers, {checked: true});

    // Add in a check to see if any customers were selected. If none, return 
    // them all without filters
    if(checkedCustomers.length == 0) {
      return customers;
    }

    // get all the unique cities that come from these checked customers
    var cities = {};
    for(i = 0, len = checkedCustomers.length; i < len; ++i) {
      // if this checked customers cities isn't already in the cities object 
      // add it
      if(!cities.hasOwnProperty(checkedCustomers[i].city)) {
        cities[checkedCustomers[i].city] = true;
      }
    }

    // Now that we have the cities that come from the checked customers, we can
    //get all customers from those cities and return them
    var ret = [];
    for(i = 0, len = customers.length; i < len; ++i) {
      // If this customer's city exists in the cities object, add it to the 
      // return array
      if(cities[customers[i].city]) {
        ret.push(customers[i]);
      } 
    }

    // we have our result!
    return ret;
  };
});

您的标记将变成以下内容:
<div data-ng-repeat="customer in customers">
  <!-- record that this customer has been selected -->
  <input type="checkbox" ng-checked="customer.checked" ng-model="customer.checked" /> {{ customer.city }}
</div>

<table>
  <!-- table heading goes here -->
  <tbody>
      <!-- use our custom filter to only display customers from the cities selected -->
      <tr data-ng-repeat="customer in customers | selectedCustomerCities">
          <td>{{ customer.firstName }}</td>
          <td>{{ customer.lastName }}</td>
          <td>{{ customer.address }}</td>
          <td>{{ customer.city }}</td>
      </tr>
  </tbody>
</table>

您可以在此Plunker链接中查看其工作状态:http://plnkr.co/edit/GlHRLKECR4jeBS7Vf7TX?p=preview

这几乎是我想要的。默认情况下,所有客户都会显示。当选中某个城市(或多个城市)的复选框时,将应用过滤器。 - Martijn
我已经更新了我的回答。更改很小: if(checkedCustomers.length == 0) { return customers; } 如果没有选中任何客户,则基本上返回所有客户。希望这对您有意义,如果您需要任何解释,请让我知道。 - Jay
这正是我想要的。我几乎都明白了,除了这个 $filter('filter')(customers, {checked: true});。你能再解释一下吗? - Martijn
在AngularJS中,您可以在HTML模板或JavaScript本身中使用$filter服务。 AngularJS自己提供了一组过滤器,例如currencylowercase等,以方便使用。他们还提供了过滤器“filter”,这是我在JavaScript中使用的过滤器。阅读过滤器服务+提供的过滤器“filter”的文档以获取更多信息。 - Jay
1
为了避免“无法读取未定义的属性'length'”错误,如果您的数据来自Web API,则必须检查“if (!angular.isUndefined(customers))”。 - Ravimallya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接