2017-09-14 5 views
0

J'ai développé une solution asp.net pour un client il y a quelques mois, dans laquelle nous utilisons AzureSearch dans une zone de saisie. Mon approche consistait à envoyer une requête ajax une fois par seconde depuis la dernière frappe de l'utilisateur. Mais notre client voulait que cela se produise toujours lors du changement de la boîte d'entrée, donc nous l'avons fait.Appels ajax asynchrones dans un champ de recherche

Le client a signalé des recherches incohérentes. C'est à cause d'une condition de concurrence, j'ai connecté les appels asynchrones et c'est ce qui s'est passé. Je pense à ajouter un délai de 0,5 sec à la saisie semi-automatique javascript. Ou y a-t-il un meilleur moyen? Comme avoir une piscine en javascript. Le contrôle que nous utilisons est jquery autocomplete facile.

Répondre

0

En fin de compte, je n'avais pas besoin d'ajouter un délai ou un accélérateur. En cochant son site officiel, j'ai découvert deux propriétés très utiles dans jquery-facile autocomplete, qui sont:

  • matchResponseProperty: Pour éviter les conditions de course, depuis le dernier appel ajax ne dois pas neccessarily être la dernière réponse de le service backend, il prendra la dernière réponse qui a une propriété nommée comme spécifié avec cet attribut, qui correspond au texte actuel dans l'entrée. ListLocation: J'essayais de rendre un json avec une liste anonyme d'éléments et une propriété appelée InputPhrase, jusqu'à ce que j'arrive à cela, j'ai donc spécifié l'emplacement de la liste dans l'objet de réponse de base et utilisé ce modèle pour la réponse .

    public class SearchViewModel 
    { 
        public List<dynamic> Items { get; set; } 
        public string InputPhrase { get; set; } 
    } 
    

Enfin, je mets matchResponseProperty à « InputPhrase », et listLocation à « Articles »

+0

Ne pas oublier de marquer cette réponse – Soviut

+0

je peux le faire demain – LunielleDev

1

Ce que vous faites s'appelle un "debounce". Un rebond est quand vous avez un compte à rebours commence à décompter quand un utilisateur commence l'entrée. Si elles entrent plus d'entrée avant la fin de la minuterie, la minuterie est réinitialisée et recommence à compter à nouveau. Ce n'est que lorsque la minuterie se termine que l'appel AJAX est fait. Dans ce cas, un délai de 200 ms est ce que la plupart des gens considèrent comme une réponse à la recherche.

Cependant, si vous voulez vraiment que les résultats se déversent au fur et à mesure que l'utilisateur tape, ce que vous devez à la place s'appelle un "accélérateur". Un étranglement est similaire à un rebond, sauf qu'il se déclenche à intervalles réguliers, plutôt que d'attendre que l'entrée s'arrête. Pour en construire un, vous auriez toujours une minuterie, cependant, vous ne le réinitialiserez pas à chaque fois que l'utilisateur saisira plus de données. Au lieu de cela, vous utiliseriez un booléen pour savoir si une nouvelle entrée avait été entrée ou non. Lorsque la minuterie se termine, elle vérifie si le booléen est vrai, si c'est le cas, mettez-le à false et redémarrez le compte à rebours.

Vous pouvez améliorer l'une ou l'autre méthode en gardant la trace si un appel AJAX était déjà en cours. Dans les deux cas, si la minuterie arrive à expiration et que le suivi booléen si un appel est en cours est vrai, redémarrez le minuteur.

Les fichiers debounce et throttle sont déjà disponibles dans plusieurs bibliothèques d'utilitaires, telles que lodash. Vous pouvez les utiliser pour envelopper vos gestionnaires d'événements existants.

var myInputChangeHandler = function() { 
    // do ajax call 
}; 

// throttled handler will only be called every 200 ms... 
var throttled = _.throttle(myInputChangeHandler, 200); 
// ...no matter how many times this event fires 
jQuery('input[type=text]').on('change', throttled);