【问题标题】:Search filter not working for multiple fields with common model搜索过滤器不适用于具有通用模型的多个字段
【发布时间】:2016-08-19 21:43:31
【问题描述】:

我正在尝试创建一个搜索框,它可以通过对象的各种属性单独过滤搜索。
在我当前的解决方案中,我必须创建一个模拟内置搜索的自定义搜索功能:

<!DOCTYPE html>
<html ng-app="m1">
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js'></script>
  </head>
  <body ng-controller="c1">
    <div>
      Filter
      <select ng-model="filterKey">
        <option value="bookId">By Id</option>
        <option value="bookTitle">By Title</option>
        <option value="author">By Author</option>
        <option value="cost">By Cost</option>
      </select>
      <input type="text" ng-model="filterValue">
    </div>
    <table>
      <tr>
        <th>SI. No.</th>
        <th>Details</th>
      </tr>
      <tr custom-tr ng-repeat="book in books | filter: bookFilter(filterKey, filterValue)">
        <td>{{ $index + 1 }}</td>
        <td>
          <table>
            <tr>
              <td>Book ID:</td>
              <td>{{book.bookId}}</td>
            </tr>
            <tr>
              <td>Book Title:</td>
              <td>{{book.bookTitle}}</td>
            </tr>
            <tr>
              <td>Book Author:</td>
              <td>{{book.author}}</td>
            </tr>
            <tr>
              <td>Book Cost:</td>
              <td>{{book.cost}}</td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
  <script type="text/javascript">
    var m1 = angular.module("m1", []);

    m1.controller('c1',function($scope)
    {
      $scope.books = [
      {
          "bookId": 101,
          "bookTitle": "Angular JS",
          "author": "Green",
          "cost":375,
      },
      {
          "bookId": 102,
          "bookTitle": "Instant AngularJS Starter",
          "author": "Dan Menard",
          "cost":150,
      },
      {
          "bookId": 103,
          "bookTitle": "Ng-Book: The Complete Book on AngularJS",
          "author": "Ari Lerner",
          "cost":4657,
      }];

      $scope.bookFilter = function(filterKey, filterValue)
      {
        return function(book)
        {
          if(!filterKey || !filterValue)
          {
            return true;
          }
          // Emulating the built-in search algorithm
          return String(book[filterKey]).toLowerCase().includes(filterValue.toLowerCase());
        };
      };
    });
  </script>
</html>

我想在不手动编写搜索算法的情况下做同样的事情(并且不需要同时编写更多代码)。

我目前的尝试是这样的:

<!DOCTYPE html>
<html ng-app="m1">
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js'></script>
  </head>
  <body ng-controller="c1">
    <div>
      Filter
      <select ng-model="filterKey">
        <option value="bookId">By Id</option>
        <option value="bookTitle">By Title</option>
        <option value="author">By Author</option>
        <option value="cost">By Cost</option>
      </select>
      <input type="text" ng-model="filterValue">
    </div>
    <table>
      <tr>
        <th>SI. No.</th>
        <th>Details</th>
      </tr>
      <tr custom-tr ng-repeat="book in books | filter: {filterKey: filterValue}">
        <td>{{ $index + 1 }}</td>
        <td>
          <table>
            <tr>
              <td>Book ID:</td>
              <td>{{book.bookId}}</td>
            </tr>
            <tr>
              <td>Book Title:</td>
              <td>{{book.bookTitle}}</td>
            </tr>
            <tr>
              <td>Book Author:</td>
              <td>{{book.author}}</td>
            </tr>
            <tr>
              <td>Book Cost:</td>
              <td>{{book.cost}}</td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
  <script type="text/javascript">
    var m1 = angular.module("m1", []);

    m1.controller('c1',function($scope)
    {
      $scope.books = [
      {
          "bookId": 101,
          "bookTitle": "Angular JS",
          "author": "Green",
          "cost":375,
      },
      {
          "bookId": 102,
          "bookTitle": "Instant AngularJS Starter",
          "author": "Dan Menard",
          "cost":150,
      },
      {
          "bookId": 103,
          "bookTitle": "Ng-Book: The Complete Book on AngularJS",
          "author": "Ari Lerner",
          "cost":4657,
      }];
    });
  </script>
</html>

但这不起作用,可能是因为&lt;tr custom-tr ng-repeat="book in books | filter: {filterKey: filterValue}"&gt; 行中的filterKey 没有被正确读取。

我怀疑是因为如果我手动编写密钥,它可以工作:

<tr custom-tr ng-repeat="book in books | filter: {'author': filterValue}">

但是,这样我将不得不为对象中存在的每个键编写过滤器表达式(如果有 20 个键我们会做什么?!!)。

所以,我的问题是如何实现搜索功能:

  • 没有尝试自己模拟搜索算法。
  • 无需为每个键单独编写过滤器表达式

编辑:
我刚刚尝试了多个字段:

<tr custom-tr ng-repeat="book in books | filter: {'author': filterValue} | filter: {'cost': filterValue}">

它根本不工作。
那么,无论如何,正确的做法是什么?

【问题讨论】:

    标签: javascript angularjs angularjs-filter angular-ngmodel


    【解决方案1】:

    你在寻找这样的东西吗?

      $scope.getFilteredBooks = function() {
        var filter = {};
        filter[$scope.filterKey] = $scope.filterValue;
        return filterFilter($scope.books, filter);
      };
    

    Plunker

    【讨论】:

    • 这是一个很好的解决方案,效果很好!但它不是过滤器,对吧?你能解释一下为什么我的第一次尝试没有成功吗?并且可以通过过滤器来完成吗?
    • 您可以使用计算属性名称,它是 ES2015 的一部分,并且不被一些现代浏览器支持。你可以看到browser compatibility。语法如下:"book in books | filter: {[filterKey] :filterValue}.
    • 太好了!我认为您应该将此添加到答案中;它可能对很多人都有帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2011-07-29
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多