web-dev-qa-db-fra.com

JQuery - Stockage de la réponse ajax dans une variable globale

Je suis encore un peu un débutant sur jQuery et la scène ajax, mais j'ai une requête $ .ajax effectuant un GET pour extraire des fichiers XML (~ 6 Ko ou moins), mais pour la durée que l'utilisateur dépense sur cette page, le contenu XML doit pas/ne changera pas (cette conception ne peut pas être modifiée, je n'ai pas non plus le droit de modifier le fichier XML car je le lis ailleurs). Par conséquent, j'ai une variable globale dans laquelle je stocke les données de réponse, et toutes les recherches ultérieures sur les données sont effectuées sur cette variable, de sorte qu'il n'est pas nécessaire de faire plusieurs demandes.

Étant donné que le fichier XML peut augmenter, je ne suis pas sûr qu'il s'agisse de la meilleure pratique et, venant également de Java, mes réflexions sur les variables publiques globales sont généralement négatives.

La question que je me pose est donc de savoir s'il pourrait y avoir une meilleure façon de procéder, et si cela pose des problèmes de mémoire si le fichier se développe à une taille de fichier ridicule.

Je suppose que les données pourraient être transmises à certaines fonctions de type getter/setter à l'intérieur de l'objet xml, ce qui résoudrait mes problèmes de variables publiques globales, tout en soulevant la question de savoir si je devrais stocker la réponse dans l'objet lui-même.

Par exemple, ce que je fais actuellement est:

// top of code
var xml;
// get the file
$.ajax({
  type: "GET",
  url: "test.xml",
  dataType: "xml",
  success : function(data) {
    xml = data;
  }
});
// at a later stage do something with the 'xml' object
var foo = $(xml).find('something').attr('somethingElse');
62
Dom

Il n'y a aucun moyen de le contourner sauf de le stocker. La pagination en mémoire devrait y réduire les problèmes potentiels.

Je suggérerais, au lieu d'utiliser une variable globale appelée 'xml', de faire quelque chose de plus semblable à ceci:

var dataStore = (function(){
    var xml;

    $.ajax({
      type: "GET",
      url: "test.xml",
      dataType: "xml",
      success : function(data) {
                    xml = data;
                }
    });

    return {getXml : function()
    {
        if (xml) return xml;
        // else show some error that it isn't loaded yet;
    }};
})();

puis y accéder avec:

$(dataStore.getXml()).find('something').attr('somethingElse');
30
Luke Schafer

Voici une fonction qui fait assez bien le travail. Je ne pouvais pas obtenir la meilleure réponse ci-dessus au travail.

jQuery.extend({
    getValues: function(url) {
        var result = null;
        $.ajax({
            url: url,
            type: 'get',
            dataType: 'xml',
            async: false,
            success: function(data) {
                result = data;
            }
        });
       return result;
    }
});

Ensuite, pour y accéder, créez la variable comme suit:

var results = $.getValues("url string");
66
Charles Guilbert

Cela a fonctionné pour moi: 

var jqxhr = $.ajax({
    type: 'POST',       
    url: "processMe.php",
    data: queryParams,
    dataType: 'html',
    context: document.body,
    global: false,
    async:false,
    success: function(data) {
        return data;
    }
}).responseText;

alert(jqxhr);
// or...
return jqxhr;

Important à noter: global: false, async:false et enfin responseText chaînés à la demande $.ajax

33
Phil Lowe

Vous n'avez rien à faire de ça. J'ai rencontré le même problème avec mon projet. vous effectuez un appel de fonction dans le rappel en cas de succès pour réinitialiser la variable globale. Tant que le javascript asynchrone est défini sur false, il fonctionnera correctement. Voici mon code. J'espère que ça aide.

var exists;

//function to call inside ajax callback 
function set_exists(x){
    exists = x;
}

$.ajax({
    url: "check_entity_name.php",
    type: "POST",
    async: false, // set to false so order of operations is correct
    data: {entity_name : entity},
    success: function(data){
        if(data == true){
            set_exists(true);
        }
        else{
            set_exists(false);
        }
    }
});
if(exists == true){
    return true;
}
else{
    return false;
}

J'espère que cela vous aide.

16
Dom

votre problème peut ne pas être lié à une étendue locale ou globale, sinon au décalage du serveur entre l'exécution de la fonction "success" et le moment où vous essayez d'extraire des données de votre variable.

il est probable que vous essayez d’imprimer le contenu de la variable avant le déclenchement de la fonction ajax "success".

8
vortex

Vous trouverez peut-être plus facile de stocker les valeurs de réponse dans un élément DOM, car elles sont accessibles globalement:

<input type="hidden" id="your-hidden-control" value="replace-me" />

<script>
    $.getJSON( '/uri/', function( data ) {
        $('#your-hidden-control').val( data );
    } );
</script>

Cela présente l'avantage de ne pas avoir besoin de définir async sur false. Il est clair que cela dépend de ce que vous essayez d’atteindre.

7
afit
        function getJson(url) {
            return JSON.parse($.ajax({
                type: 'GET',
                url: url,
                dataType: 'json',
                global: false,
                async: false,
                success: function (data) {
                    return data;
                }
            }).responseText);
        }

        var myJsonObj = getJson('/api/current');

Cela marche!!!

5
DarthVader
     function get(a){
            bodyContent = $.ajax({
                  url: "/rpc.php",
                  global: false,
                  type: "POST",
                  data: a,
                  dataType: "html",
                  async:false
               } 
            ).responseText;
            return bodyContent;

  }
3
Edmhs

J'ai vraiment eu du mal à intégrer les résultats de jQuery ajax dans mes variables au stade "document.ready". 

le fichier ajax de jQuery se chargerait dans mes variables lorsqu'un utilisateur déclencherait un événement "onchange" d'une zone de sélection après le chargement de la page, mais les données ne fourniraient pas les variables lors du chargement initial de la page. 

J'ai essayé beaucoup, beaucoup, beaucoup de méthodes différentes, mais c'est finalement la méthode de Charles Guilbert qui a fonctionné le mieux pour moi. 

Chapeau à Charles Guilbert! En utilisant sa réponse, je peux obtenir des données dans mes variables, même lors du premier chargement de ma page. 

Voici un exemple de script de travail:

    jQuery.extend
    (
        {
            getValues: function(url) 
            {
                var result = null;
                $.ajax(
                    {
                        url: url,
                        type: 'get',
                        dataType: 'html',
                        async: false,
                        cache: false,
                        success: function(data) 
                        {
                            result = data;
                        }
                    }
                );
               return result;
            }
        }
    );

    // Option List 1, when "Cats" is selected elsewhere
    optList1_Cats += $.getValues("/MyData.aspx?iListNum=1&sVal=cats");

    // Option List 1, when "Dogs" is selected elsewhere
    optList1_Dogs += $.getValues("/MyData.aspx?iListNum=1&sVal=dogs");

    // Option List 2, when "Cats" is selected elsewhere
    optList2_Cats += $.getValues("/MyData.aspx?iListNum=2&sVal=cats");

    // Option List 2, when "Dogs" is selected elsewhere
    optList2_Dogs += $.getValues("/MyData.aspx?iListNum=2&sVal=dogs");
2
CityPickle

Couru dans cela aussi. Beaucoup de réponses, mais un seul correct que je vais fournir. La clé est de faire votre appel $ .ajax..sync!

$.ajax({  
    async: false, ...
2
stvn

Similaire à la réponse précédente:

<script type="text/javascript">

    var wait = false;

    $(function(){
        console.log('Loaded...');
        loadPost(5);
    });

    $(window).scroll(function(){
      if($(window).scrollTop() >= $(document).height() - $(window).height()-100){
        // Get last item
        var last = $('.post_id:last-of-type').val();
        loadPost(1,last);
      }
    });

    function loadPost(qty,offset){
      if(wait !== true){

        wait = true;

        var data = {
          items:qty,
          oset:offset
        }

        $.ajax({
            url:"api.php",
            type:"POST",
            dataType:"json",
            data:data,
            success:function(data){
              //var d = JSON.parse(data);
              console.log(data);
              $.each(data.content, function(index, value){
                $('#content').append('<input class="post_id" type="hidden" value="'+value.id+'">')
                $('#content').append('<h2>'+value.id+'</h2>');
                $('#content').append(value.content+'<hr>');
                $('#content').append('<h3>'+value.date+'</h3>');
              });
              wait = false;
            }
        });
      }
    }
</script>
0
Kyle Coots

Je sais que le fil est vieux, mais je pensais que quelqu'un d'autre pourrait trouver cela utile. Selon le jquey.com

var bodyContent = $.ajax({
  url: "script.php",
  global: false,
  type: "POST",
  data: "name=value",
  dataType: "html",
  async:false,
  success: function(msg){
     alert(msg);
  }
}).responseText;

aiderait à obtenir le résultat directement dans une chaîne . Notez le .responseText; partie.

0
user759740

OMI, vous pouvez stocker ces données dans la variable globale. Mais il vaudra mieux utiliser un nom plus unique ou un espace de nom:

MyCompany = {};

...
MyCompany.cachedData = data;

Il est également préférable d’utiliser JSON à ces fins. Les données au format JSON sont généralement beaucoup plus petites que les mêmes données au format XML.

0
zihotki

Nous suggérons d'éviter d'extraire des fichiers XML volumineux sur le serveur: la variable "xml" doit être utilisée comme un cache, et non comme le magasin de données lui-même.

Dans la plupart des scénarios, il est possible d'examiner le cache et de voir si vous devez demander au serveur d'obtenir les données souhaitées. Cela rendra votre application plus légère et plus rapide.

à la vôtre, jrh.

0
jrharshath

Les réponses .get sont mises en cache par défaut. Par conséquent, vous ne devez absolument rien faire pour obtenir les résultats souhaités.

0
redsquare