5

我有一个大数据列表(4000 多个项目)。开始输入时 - 我的浏览器冻结(最多 15 秒)。所以我需要关闭自动过滤功能,并将过滤功能绑定到按钮点击。通过谷歌寻找答案没有结果。我怎么能这样做?请帮帮我 :)

代码:

<input ng-model="search.phone" type="text" placeholder="Телефон...">
<input ng-model="search.name" type="text" placeholder="Имя...">
<input ng-model="search.city" type="text" placeholder="Город...">

<div ng-repeat="user in users | filter:search" class="user_block" ng-include src="userTemplate"></div>

和控制器:

app.controller("smsCtrl", ['$scope', 'smsData', 'createDialog', '$http', '$filter', function($scope, smsData, createDialog, $http, $filter){...}
4

3 回答 3

10

我在帮助同事时遇到了类似的事情(尽管在我们的案例中需要手动触发搜索的过滤),并提出了一个类似但稍微简单一些的解决方案。

使用您原来的重复 div。

<div ng-repeat="user in users | filter:search">
    ...
</div>

创建一个对象来存储您的用户输入。

$scope.search = {};
$scope.userInput = {};

将您的输入附加到此用户输入对象。

<input type="text" ng-model="userInput.name" />
<input type="text" ng-model="userInput.phone" />
<input type="text" ng-model="userInput.city" />

创建一个循环用户输入对象的属性并将它们复制到您的搜索对象的函数。

$scope.applySearch = function() {
    for(prop in $scope.userInput) {
        $scope.search[prop] = $scope.userInput[prop];
    }
};

最后,创建一个按钮来调用您的搜索功能。

<button ng-click="applySearch()">Search</search>

我希望这可以帮助别人。

于 2015-10-01T15:47:50.110 回答
0

也许您可以尝试在其上添加去抖动并忘记按钮。

按照一个不错的去抖动代码的链接来应用由 Lars Gersmann 创建的任何 DOM。您可以在文章末尾查看他的 JSFiddle 示例,了解它是如何工作的。

来自 GitHub 上 AngularJS 项目的 pull request #2129:

此外,ng-update-model-debounce 属性将允许在最后一次触发事件之后推迟实际的模型更新。此功能在单选按钮中不可用。

即 ng-update-model-debounce="500" for 500ms

按照下面的一个很好的方法来了解如何使用 debounce

/**
 * uiDebounce service provides a mechanism for creating a wrapper around a function 
 * that ensures that the wrapped function is not called more frequently than a
 * given time interval.
 *
 * @param {!Function} func The function to be wrapped (debounced)
 * @param {number} wait How long between called to func
 * @param {Boolean} immediate If true then the function is invoked on the first call to the
 * wrapper function, otherwise the call will not happen until after the wait time has expired
 * @return {Function} A debounced wrapper around the func function.
 *
 * @example
 * function lookup(id) { ... lookup something ... }
 * var debounceLookup = debounce(lookup, 2000, false);
 * $scope.doLookup = function(msg) {
 *   var promise = debounceLookup(msg);
 *   console.log('called lookup: ', promise);
 *   promise.then(function(value) {
 *     console.log('lookup returned:', value);
 *   });
 * };
 */
angular.module('ui.services').factory('uiDebounce', function($timeout, $q) {
  return function(func, wait, immediate) {
    var timeout;
    var deferred = $q.defer();
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if(!immediate) {
          deferred.resolve(func.apply(context, args));
          deferred = $q.defer();
        }
      };
      var callNow = immediate && !timeout;
      if ( timeout ) {
        $timeout.cancel(timeout);
      }
      timeout = $timeout(later, wait);
      if (callNow) {
        deferred.resolve(func.apply(context,args));
        deferred = $q.defer();
      }
      return deferred.promise;
    };
  };
});

来源:Github - Angular-UI

于 2013-11-05T13:28:53.600 回答
0

我找到了解决方案!

改变:

<div ng-repeat="user in users | filter:search" class="user_block" ng-include src="userTemplate"></div>

到:

<div ng-repeat="user in users" ng-hide="user.excludedByFilter" class="sms_user_block" ng-include src="userTemplate"></div>

向控制器添加“applySearchFilter”功能

    $scope.applySearchFilter = function() {
        var nameFilter = $scope.filters.name.toLowerCase();
        var phoneFilter = $scope.filters.phone;
        var cityFilter = $scope.filters.city;
        var showAll = 0 === nameFilter.length && 0 === phoneFilter.length && 0 === cityFilter.length;
        angular.forEach($scope.users, function(user) {
            if (showAll) {
                user.excludedByFilter = false;
            } else {
                user.excludedByFilter = (user.name.toLowerCase().indexOf(nameFilter) === -1) 
                                        || (user.phone.indexOf(phoneFilter) === -1) 
                                        || (user.city.indexOf(cityFilter) === -1);
            }
        });
    }

并为过滤器按钮添加 html 代码:

<a class="btn btn-primary" href="#" ng-click="applySearchFilter()">Apply filters</a>

这行得通!

*注意,我在输入中将 ng-model="search.*" 重命名为 ng-model="filters.*"。

于 2013-11-07T14:41:07.307 回答