javascript 单击“应用”按钮后应用 angularjs 过滤器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19784795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Applying a angularjs filter after "Apply" button click
提问by sashok1337
I have a big list of data (4000+ items). When start typing - my browser freezes (up to 15 sec). So i need to turn off auto-filter feature, and bind filter function to the button click. Looking for answer via Google gave no results. How i can do this? Help me please :)
我有一个很大的数据列表(4000 多个项目)。开始输入时 - 我的浏览器冻结(最多 15 秒)。所以我需要关闭自动过滤功能,并将过滤功能绑定到按钮点击。通过谷歌寻找答案没有结果。我怎么能做到这一点?请帮帮我 :)
Code:
代码:
<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>
and controller:
和控制器:
app.controller("smsCtrl", ['$scope', 'smsData', 'createDialog', '$http', '$filter', function($scope, smsData, createDialog, $http, $filter){...}
采纳答案by sashok1337
I found the solution!
我找到了解决方案!
Change:
改变:
<div ng-repeat="user in users | filter:search" class="user_block" ng-include src="userTemplate"></div>
To:
到:
<div ng-repeat="user in users" ng-hide="user.excludedByFilter" class="sms_user_block" ng-include src="userTemplate"></div>
Add "applySearchFilter" function to controller
向控制器添加“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);
}
});
}
And add html code for filter button:
并为过滤器按钮添加 html 代码:
<a class="btn btn-primary" href="#" ng-click="applySearchFilter()">Apply filters</a>
And this works!
这有效!
*Note, that I renamed ng-model="search.*" to ng-model="filters.*" in inputs.
*注意,我在输入中将 ng-model="search.*" 重命名为 ng-model="filters.*"。
回答by Adam Nierzad
I've encountered something similar while helping a colleague (although the filtering of the search being manually triggered was desirable in our case) and came up with a similar but slightly more simple solution.
我在帮助一位同事时遇到了类似的事情(尽管在我们的案例中手动触发的搜索过滤是可取的),并提出了一个类似但稍微简单的解决方案。
Use your original repeating div.
使用您原来的重复 div。
<div ng-repeat="user in users | filter:search">
...
</div>
Create an object for storing your user input.
创建一个对象来存储您的用户输入。
$scope.search = {};
$scope.userInput = {};
Attach your input to this user input object.
将您的输入附加到此用户输入对象。
<input type="text" ng-model="userInput.name" />
<input type="text" ng-model="userInput.phone" />
<input type="text" ng-model="userInput.city" />
Create a function which loops the properties of the user input object and copies them to your search object.
创建一个循环用户输入对象的属性并将它们复制到您的搜索对象的函数。
$scope.applySearch = function() {
for(prop in $scope.userInput) {
$scope.search[prop] = $scope.userInput[prop];
}
};
Finally, create a button to call your search function.
最后,创建一个按钮来调用您的搜索功能。
<button ng-click="applySearch()">Search</search>
I hope this helps someone.
我希望这可以帮助别人。
回答by dnlbox
Maybe you can try add a debounce on it and forget the button.
也许您可以尝试在其上添加去抖动并忘记按钮。
Follow a linkto a nice debounce code to apply any DOM created by Lars Gersmann. You can look his JSFiddle example of how its gonna work at the end of the article.
按照链接到一个很好的去抖动代码来应用 Lars Gersmann 创建的任何 DOM。您可以在文章末尾查看他的 JSFiddle 示例,了解其将如何工作。
From pull request #2129 of AngularJS project at GitHub:
来自 GitHub 上 AngularJS 项目的 pull request #2129:
Also, a ng-update-model-debounce attribute will allow defering the actual model update after the last triggered event. This feature is not available in radio buttons.
I.e. ng-update-model-debounce="500" for 500ms
此外,ng-update-model-debounce 属性将允许在上次触发事件之后推迟实际模型更新。此功能在单选按钮中不可用。
即 ng-update-model-debounce="500" 500ms
Follow bellow a nice approach of how to use 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;
};
};
});
Source: Github - Angular-UI