Tengo un problema de rendimiento que parece que no puedo resolver. Tengo una búsqueda instantánea, pero es un poco lento, ya que comienza a buscar en cada keyup()
.
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:searchText">
<span>{{entry.content}}</span>
</div>
Los datos JSON ni siquiera son tan grandes, 300KB solamente, creo que lo que necesito conseguir es poner un retardo de ~1 seg en la búsqueda para esperar a que el usuario termine de escribir, en lugar de realizar la acción en cada pulsación de tecla. AngularJS hace esto internamente, y después de leer docs y otros temas aquí no pude encontrar una respuesta específica.
Agradecería cualquier indicación sobre cómo puedo retrasar la búsqueda instantánea.
ACTUALIZACIÓN
Ahora es más fácil que nunca (Angular 1.3), basta con añadir una opción debounce en el modelo.
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
.
Plunker actualizado: http://plnkr.co/edit/4V13gK
Documentación sobre ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Método antiguo:
Aquí's otro método sin dependencias más allá de angular sí mismo.
Es necesario establecer un tiempo de espera y comparar su cadena actual con la versión anterior, si ambos son iguales, entonces se realiza la búsqueda.
$scope.$watch('searchStr', function (tmpStr)
{
if (!tmpStr || tmpStr.length == 0)
return 0;
$timeout(function() {
// if searchStr is still the same..
// go ahead and retrieve the data
if (tmpStr === $scope.searchStr)
{
$http.get('//echo.jsontest.com/res/'+ tmpStr).success(function(data) {
// update the textarea
$scope.responseData = data.res;
});
}
}, 1000);
});
y esto va en su vista:
<input type="text" data-ng-model="searchStr">
<textarea> {{responseData}} </textarea>
El plunker obligatorio: http://plnkr.co/dAPmwf
(Véase la respuesta más abajo para una solución Angular 1.3.)
El problema aquí es que la búsqueda se ejecutará cada vez que el modelo cambia, que es cada acción keyup en una entrada.
Habría maneras más limpias de hacer esto, pero probablemente la forma más fácil sería cambiar la vinculación de modo que usted tiene una propiedad $scope definido dentro de su controlador en el que opera su filtro. De esta forma puedes controlar la frecuencia con la que se actualiza la variable $scope. Algo como esto:
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http, $timeout) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
// This is what you will bind the filter to
$scope.filterText = '';
// Instantiate these variables outside the watch
var tempFilterText = '',
filterTextTimeout;
$scope.$watch('searchText', function (val) {
if (filterTextTimeout) $timeout.cancel(filterTextTimeout);
tempFilterText = val;
filterTextTimeout = $timeout(function() {
$scope.filterText = tempFilterText;
}, 250); // delay 250 ms
})
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:filterText">
<span>{{entry.content}}</span>
</div>
Debounced / throttled model updates for angularjs :
En su caso no hay nada más que hacer que utilizar la directiva en el código jsfiddle así:
<input
id="searchText"
type="search"
placeholder="live search..."
ng-model="searchText"
ng-ampere-debounce
/>
Es básicamente una pequeña pieza de código que consiste en una única directiva angular llamada "ng-ampere-debounce" utilizando http://benalman.com/projects/jquery-throttle-debounce-plugin/ que se puede adjuntar a cualquier elemento dom. La directiva reordena los manejadores de eventos adjuntos para que pueda controlar cuando acelerar los eventos.
Puedes usarla para estrangular/debotar
Echa un vistazo :
La directiva formará parte del framework Orangevolt Ampere (https://github.com/lgersman/jquery.orangevolt-ampere).