Я применил функцию пользовательского поиска для моего углового приложения js.
Для этого я вызвал запрос Ajax для извлечения данных. Этот вызов происходит в событии изменения, и поэтому он несколько раз вызывает мой Ajax.
Пожалуйста, предлагайте, поскольку я новичок в угловых js.
Вы можете использовать задержку (время простоя). Например, я набираю текстовое поле поиска. Если я простаиваю в течение 200 мс, 400 мс или в любое другое время, вы можете вызвать запрос AJAX.
Если я напечатаю salman, он назовет api 6 раз. но предположим, что у нас будет свободное время. мы будем вызывать, когда пользователь простаивает в течение определенного времени.
Чтобы реализовать его в угловом, вы можете использовать. $ watch или bootstrap
Таким образом, ваш лучший выбор - дать себе немного задержки. Как отметил Акаш, вам нужно выбрать время задержки, которое вы считаете приемлемым. Вам также необходимо убедиться, что запрос сделан только после задержки.
Вот один из способов сделать это:
//In your controller
var _timeout;
$scope.fetchSearchResults = function(){
//We will clear the previous timeout because a key has been pressed
clearTimeout(_timeout);
//Set the timeout - if no key is pressed, it will execute. Else the line above will clear it.
_timeout = setTimeout(function(){
var keyword = $scope.searchKeyword.name;
//Do your AJAX request here
//We have delayed the request by 400ms - but you can change it as you please.
}, 400);
}
Ваш HTML:
<!-- Then in your HTML something similar to: -->
<input ng-model="searchKeyword.name" ng-keyup="fetchSearchResults()" />
Редактировать:
Если вы хотите пойти "чистым" угловым способом, вы сделаете это так:
//In your controller
//NOTE: make sure you've injected $timeout into your controller
var _timeout;
$scope.fetchSearchResults = function(){
//We will clear the previous timeout because a key has been pressed
$timeout.cancel(_timeout);
//Set the timeout - if no key is pressed, it will execute. Else the line above will clear it.
_timeout = $timeout(function(){
var keyword = $scope.searchKeyword.name;
//Do your AJAX request here
//We have delayed the request by 400ms - but you can change it as you please.
}, 400);
}
setTimeout
вместо $timeout
сервиса angular?
Я определенно рекомендую ответить @jeanpaul на "debouncing".
В дополнение к этому, когда у вас есть потенциал для нескольких одновременных запросов AJAX и вы хотите обрабатывать самые последние, может потребоваться проверить, какой запрос он находится в вашем обработчике ответов. Это особенно важно, когда ответы не всегда поступают в том порядке, в котором они были запрошены (т.е. Более ранний запрос занимает больше времени, чем ответ, чем более поздний)
Способ решения этого - это что-то вроде:
var activeRequest;
function doRequest(params){
// reqId is the id for the request being made in this function call
var reqId = angular.toJson(params); // I usually md5 hash this
// activeRequest will always be the last reqId sent out
activeRequest = reqId;
$http.get('/api/something', {data: params})
.then(function(res){
if(activeRequest == reqId){
// this is the response for last request
}
else {
// response from previous request (typically gets ignored)
}
});
}
Вы уже приняли ответ, но я хочу поделиться с вами некоторым кодом.
myapp.factory('formService', ['$http', '$filter', '$q', '$timeout', function ($http, $filter, $q, $timeout) {
var service = {};
service.delayPromise = null;
service.canceler = null;
service.processForm = function (url, formData, delay) {
if (service.delayPromise)
$timeout.cancel(service.delayPromise);
if (service.canceler)
service.canceler.resolve();
service.canceler = $q.defer();
service.delayPromise = $timeout(function (service) {
return service;
}, delay, true, service);
return service.delayPromise.then(function (service) {
service.delayPromise = null;
return $http({
method : 'POST',
url : url,
timeout : service.canceler.promise,
data : formData
});
})
}
return service;
]);
Что это делает. Он предоставляет formService
с функцией processForm
, с formData
url
, formData
и delay
.
processForm
задерживает передачу с помощью $timeout
. Если уже есть отложенное или ожидающее представления, оно просто отменяет его.
И в вашем контроллере.
myapp.controller('myCtrl', ['formService', function (formService) {
$scope.formData = {};
$scope.pageData = {};
$scope.$watchCollection('formData', function (formData, oldData, scope) {
if (!angular.equals(formData, oldData)) {
var event;
formService.processForm(formData, event, 500).then(function (response) {
if (response.data instanceof Object)
angular.copy(response.data, scope.pageData);
});
}
});
}]);