J'ai un problème de performances que je n'arrive pas à résoudre. J'ai une recherche instantanée mais elle est un peu lente, car elle commence à chercher sur chacun 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>
Les données JSON ne sont même pas si volumineuses, 300 Ko seulement, je pense que ce que je dois accomplir est de mettre un délai d'environ 1 seconde sur la recherche pour attendre que l'utilisateur ait fini de taper, au lieu d'exécuter l'action à chaque frappe. AngularJS fait cela en interne, et après avoir lu des documents et d'autres sujets ici, je n'ai pas trouvé de réponse spécifique.
J'apprécierais tous les conseils sur la façon dont je peux retarder la recherche instantanée.
Réponses:
(Voir la réponse ci-dessous pour une solution angulaire 1.3.)
Le problème ici est que la recherche s'exécutera à chaque fois que le modèle change, ce qui correspond à chaque action keyup sur une entrée.
Il y aurait des moyens plus propres de le faire, mais le moyen le plus simple serait probablement de changer la liaison de sorte que vous ayez une propriété $ scope définie dans votre Controller sur laquelle votre filtre fonctionne. De cette façon, vous pouvez contrôler la fréquence à laquelle cette variable $ scope est mise à jour. Quelque chose comme ça:
JS:
HTML:
la source
ng-model
ne fonctionnera pas dans le modal de bootstrap angular-uiMETTRE À JOUR
Maintenant c'est plus facile que jamais (Angular 1.3), il suffit d'ajouter une option anti-rebond sur le modèle.
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
Plunker mis à jour:
http://plnkr.co/edit/4V13gK
Documentation sur ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Ancienne méthode:
Voici une autre méthode sans dépendances au-delà de l'angular lui-même.
Vous devez définir un délai d'expiration et comparer votre chaîne actuelle avec la version précédente, si les deux sont identiques, il effectue la recherche.
et cela va dans votre avis:
Le plunker obligatoire: http://plnkr.co/dAPmwf
la source
Dans Angular 1.3, je ferais ceci:
HTML:
Manette:
Fondamentalement, vous dites à angular de s'exécuter
myDebouncedFunction()
lorsque lamsg
variable de portée change. L'attributng-model-options="{debounce: 1000}"
garantit que celamsg
ne peut être mis à jour qu'une fois par seconde.la source
Maintenant, nous pouvons définir les options ng-model-options anti-rebond avec le temps et en cas de flou, le modèle doit être changé immédiatement, sinon, lors de l'enregistrement, il aura une valeur plus ancienne si le délai n'est pas terminé.
la source
Pour ceux qui utilisent keyup / keydown dans le balisage HTML. Cela n'utilise pas de montre.
JS
HTML
la source
Mises à jour de modèle déboncées / limitées pour angularjs: http://jsfiddle.net/lgersman/vPsGb/3/
Dans votre cas, il n'y a rien de plus à faire que d'utiliser la directive dans le code jsfiddle comme ceci:
C'est fondamentalement un petit morceau de code constitué d'une seule directive angulaire nommée "ng-ampere-debounce" utilisant http://benalman.com/projects/jquery-throttle-debounce-plugin/ qui peut être attachée à n'importe quel élément dom. La directive réorganise les gestionnaires d'événements attachés afin de pouvoir contrôler quand limiter les événements.
Vous pouvez l'utiliser pour la limitation / la suppression de * mises à jour angulaires du modèle * gestionnaire d'événements angulaires ng- [événement] * gestionnaires d'événements jquery
Jetez un œil: http://jsfiddle.net/lgersman/vPsGb/3/
La directive fera partie du framework Orangevolt Ampere ( https://github.com/lgersman/jquery.orangevolt-ampere ).
la source
Juste pour les utilisateurs redirigés ici:
Comme introduit dans,
Angular 1.3
vous pouvez utiliser l' attribut ng-model-options :la source
Je pense que la meilleure façon de résoudre ce problème est d'utiliser le plugin jQuery throttle / debounce de Ben Alman . À mon avis, il n'est pas nécessaire de retarder les événements de chaque champ de votre formulaire.
Enveloppez simplement votre fonction de gestion $ scope. $ Watch dans $ .debounce comme ceci:
la source
Une autre solution consiste à ajouter une fonctionnalité de retard à la mise à jour du modèle. La directive simple semble faire un tour:
Usage:
Donc, vous utilisez simplement
delayed-model
à la placeng-model
et définissez souhaitédata-delay
.Démo: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p=preview
la source
model: '=delayedModel'
marche? Ou pouvez-vous me diriger vers un lien où je peux le trouver?element.on('change')
se déclenche uniquement sur le flou. (1) Y a-t-il une solution? (2) comment appeler une fonction du contrôleur lors d'un changement de texte?J'ai résolu ce problème avec une directive qui consiste essentiellement à lier le modèle ng réel à un attribut spécial que je regarde dans la directive, puis en utilisant un service anti-rebond, je mets à jour mon attribut de directive, de sorte que l'utilisateur surveille la variable qui il se lie à debounce-model au lieu de ng-model.
Usage:
Et dans le contrôleur:
Démo dans jsfiddle: http://jsfiddle.net/6K7Kd/37/
le service $ debounce peut être trouvé ici: http://jsfiddle.net/Warspawn/6K7Kd/
Inspiré de la directive éventuellementBind http://jsfiddle.net/fctZH/12/
la source
Angular 1.3 aura ng-model-options anti-rebond, mais jusque-là, vous devez utiliser une minuterie comme l'a dit Josue Ibarra. Cependant, dans son code, il lance une minuterie à chaque pression de touche. De plus, il utilise setTimeout, alors que dans Angular, il faut utiliser $ timeout ou utiliser $ apply à la fin de setTimeout.
la source
Pourquoi tout le monde veut-il utiliser la montre? Vous pouvez également utiliser une fonction:
la source
Je pense que le moyen le plus simple ici est de précharger le json ou de le charger une fois
$dirty
, puis la recherche par filtre se chargera du reste. Cela vous permettra d'économiser les appels http supplémentaires et c'est beaucoup plus rapide avec des données préchargées. La mémoire fera mal, mais ça vaut le coup.la source