我在AngularJS
中使用了15个输入字段实现了高级搜索。
在页面加载中,结果集以 JSON格式从数据库返回,我只需要在客户端中进行过滤。
输入条件的等效列在结果集中可用,我只需要检查其各自的列。
我正在按JSON.stringify()
转换每一列,并使用下面的搜索参数进行检查:
$scope.filteredData = $scope.actualData.filter(function(item) {
return JSON.stringify(item.FirstName).toLowerCase().indexOf(lowerFirstName) != -1 &&
JSON.stringify(item.LastName).toLowerCase().indexOf(lowerLastName) != -1 &&
JSON.stringify(item.EmailAddress).toLowerCase().indexOf(lowerEmailAddress) != -1 &&
JSON.stringify(item.Address1).toLowerCase().indexOf(lowerAddress1) != -1 &&
JSON.stringify(item.Address2).toLowerCase().indexOf(lowerAddress2) != -1;
...... etc // upto 15 fields
});
由于我有15个输入字段,实际结果集至少包含50,000条记录。
因此,按JSON.stringify()
转换每个记录的每一列并使用搜索参数检查肯定会导致性能问题。
还有其他方法可以通过其他方法在客户端实现过滤。
我在Plunker中发布了一个示例代码,仅包含5个输入字段:http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP
答案 0 :(得分:2)
sylwester的答案是你过滤事物的正常方式。您的代码看起来只想过滤到与每个输入字段匹配的对象。您编写代码尝试查找每个属性与searchParams对象匹配的对象。那时,我没有看到找到该对象有什么好处,因为用户已经再次创建了该对象!尽管如此,这是您的代码的正确版本:
<div ng-repeat="data in actualData | filter:searchData()">
$scope.searchData = function() {
return function(item) {
return Object.keys(item).every(function(key) {
// skip the $$hashKey property Angular adds to objects
if (key === '$$hashKey') { return true; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
return item[key].toLowerCase() === $scope.searchParams[searchKey].toLowerCase();
});
};
};
出于浏览器和服务器的缘故,您确实需要限制来自服务器的数据。实现LIMIT,OFFSET系统很容易。听起来总的来说,您只需要能够在服务器上查询某个记录。
根据您的评论,您似乎肯定希望Angular内置过滤器filter:searchParams
,并且只需将searchParams
模型大写以匹配您的数据。为了好玩,我将提供更多选项以进行更精细的调整。
这个几乎模仿filter:searchParams
。您可以更改> 1
以在部分匹配开始时进行调整,或仅在两个项严格相等===
时才返回true以禁用部分匹配。这里的区别在于所有项目都会被隐藏,直到匹配为止,而filter:searchParams
会显示所有项目,然后删除不匹配的内容。
$scope.searchData = function() {
return function(item) {
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length > 1 && match;
});
};
};
最后,为了完全模仿filter:searchParams
,你只需要检查以不过滤项目,直到有用户输入并且输入足够长以开始部分匹配。
$scope.searchData = function() {
var partialMatchLength = 2;
return function(item) {
var shouldFilter = Object.keys($scope.searchParams).some(function(key) {
return $scope.searchParams[key] && $scope.searchParams[key].length >= partialMatchLength;
});
if (!shouldFilter) { return true; }
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length >= partialMatchLength && match;
});
};
};
答案 1 :(得分:1)
首先,你有{000}记录的ng-repeter
更有可能会杀死你的浏览器,所以你应该关注分页。
其次,您可以使用角度过滤器轻松过滤数据,请参阅演示
http://plnkr.co/edit/R8b8G4xCMSQmX1144UJG?p=preview
<div ng-controller="ListCtrl">
<br />
First Name:
<input type="text" id="txtFirstname" ng-model="searchParams.FirstName">
<br/>Last Name:
<input type="text" id="txtLastname" ng-model="searchParams.LastName">
<br/>Email Address:
<input type="text" id="txtEmailAddress" ng-model="searchParams.EmailAddress">
<br/>Address 1:
<input type="text" id="txtAddress1" ng-model="searchParams.Address1">
<br/>Address 2:
<input type="text" id="txtAddress2" ng-model="searchParams.Address2">
<br/>
<button class="btn btn-primary" ng-click="searchData()">Search</button>
<br />
<hr />
<b>Filtered Data(s):</b>
<div ng-repeat="data in actualData | filter:searchParams ">
<span ng-bind="data.FirstName"></span>
<span ng-bind="data.LastName"></span> |
Address : {{data.Address1}}
</div>
<hr />
</div>