javascript - AngularJS:在除一个字段外的所有字段上在 Controller 中进行过滤

标签 javascript angularjs

在我的 angularjs 应用程序中,我通过 json 获得这样的数据示例:

{"id":"1a", "name": "aaa", "emails": {{"123@123.com"}, {"123@123.info"}}},
{"id":"2a", "name": "aba", "emails": {{"23@123.com"}, {"3@123.info"}}},
{"id":"3a", "name": "aab", "emails": {{"3@123.com"}, {"3@123.info"}}},

出于性能原因,我没有为 ng-repeat 使用过滤器,而是使用 ng-show 模式...

所以在 Controller 中我有这样的代码(搜索是我的输入值):

  $scope.$watch('search', function(newVal, oldVal) {
    $scope.filteredArray = $filter('filter')($scope.users, $scope.search, newVal);
  });

但它甚至在 id 中搜索,例如我输入 a 并从 id 中获取它,但我在这里不需要字段 id...

那么如何只在特定字段中使用过滤器进行搜索呢?

最佳答案

如果您关心性能,最好的选择可能是根本不使用 $filter('filter')。假设您的数据是 JSON,您可以执行以下操作:

function contains(src, value, except) {
  var key;
  switch(typeof src) {
    case 'string':
    case 'number':
    case 'boolean':
      return String(src).indexOf(value) > -1;
    case 'object':
      except = except || [];
      for(key in src) {
        if( src.hasOwnProperty(key) &&
            except.indexOf(key) < 0 &&
            contains(src[key], value, except)
        ) {
          return true;
        }
      }
  }
  return false;
}

angular.module('app', []).
  factory('appService', function() {
    var data = [
      {"id":"1a", "name": "aaa", "emails": ["123@123.com", "123@123.info"]},
      {"id":"2a", "name": "aba", "emails": ["23@123.com", "3@123.info"]},
      {"id":"3a", "name": "aab", "emails": ["3@123.com", "3@123.info", ["1@123.com", "2@123.info"]]}
    ];
    return {
      getFilteredData: function(filter, except) {
        return filter ? data.filter(function(item) {
          return contains(item, filter, except)
        }) : data.slice(0);
      }
    }
  }).
  controller('appController', ['$scope', 'appService', function($scope, appService) {
    $scope.search = '';
    $scope.$watch('search', function(val) {
      $scope.data = appService.getFilteredData(val, ['id']);
    });
  }]);
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="appController">
    <input ng-model="search" ng-model-options="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }"/>
    <ul>
      <li ng-repeat="item in data">{{::item}}</li>
    </ul>
  </body>

</html>

上面的代码将在所有数据字段中进行深度搜索,它的项目不包括作为参数传递的字段列表(在本例中 ['id'])

提示 #1:在 Controller 内部实现业务逻辑在 Angular 中是一种不好的做法,Angular 有用于此目的的服务。

提示 #2:如果要显示大量数据集,debouncing从性能的 Angular 来看,过滤器更改将非常有益。

提示 #3:如果您的数据集项是不可变的,您可以利用 one-time binding (使用 {{::item}} 语法)并通过减少 Angular 创建的 watch 数量来加速您的应用。

关于javascript - AngularJS:在除一个字段外的所有字段上在 Controller 中进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28745387/

相关文章:

javascript - 如何在按钮内具有 ng-if 双向条件?

javascript - "canvas.toDataURL("图像/png ")"在 Firefox 中无法正常工作

javascript - AngularJS - 如何处理 Controller /服务中所需数据的长时间运行请求

javascript - JQuery Mobile、查询字符串和多页面 ID

javascript - 子组件如何在不监听生命周期方法的情况下从父组件接收 props?

javascript - 减少 Phonegap 项目大小 (Android)

javascript - 如果只有本地 Angular 应用程序调用它为真 Controller ,则执行路由

javascript - Angular - 从 JavaScript 重定向到路由

javascript - orderBy 无法正常工作

javascript - 如何在 Angular 中将 ng-attr-id 转换为 id