2009-05-25 6 views
58

Я все еще немного новичок в jQuery и сценарии ajax, но у меня есть запрос $ .ajax, выполняющий GET для извлечения некоторых файлов XML (~ 6 КБ или менее), однако для продолжительность, которую пользователь тратит на эту страницу, что содержимое XML не должно/не измениться (этот проект я не могу изменить, у меня также нет доступа к изменению файла XML, поскольку я его читаю откуда-то еще). Поэтому у меня есть глобальная переменная, в которой хранятся данные ответа, и любые последующие запросы на данные выполняются для этой переменной, поэтому не нужно делать несколько запросов.JQuery - Сохранение ответа ajax в глобальной переменной

Учитывая, что XML-файл может увеличиться, я не уверен, что это лучшая практика, а также исходящие из java-фона мои мысли о глобальных общедоступных переменных, как правило, не имеют значения.

Таким образом, у меня есть вопрос, может ли быть лучший способ сделать это, и вопрос о том, вызывает ли это какие-либо проблемы с памятью, если файл расширяется до какого-то смешного размера файла?

Я полагаю, что данные могут быть переданы в некоторые функции типа getter/setter внутри объекта xml, что позволило бы решить мои глобальные проблемы с переменными public, но все же вызывает вопрос о том, следует ли хранить ответ внутри самого объекта.

Например, что я в настоящее время сделать это:

// 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'); 
+6

ПРЕДУПРЕЖДЕНИЕ ДЛЯ ИНТЕЛЛЕКТУАЛЬНЫХ ИССЛЕДОВАНИЙ. Многие решения ниже используют async: false. Здесь будут драконы –

ответ

28

Там нет никакого способа вокруг него, кроме как для ее хранения. Пейджинг памяти должен уменьшить потенциальные проблемы.

Я хотел бы предложить вместо того, чтобы использовать глобальную переменную «XML», сделать что-то больше, как это:

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; 
    }}; 
})(); 

обращаться к нему с:

$(dataStore.getXml()).find('something').attr('somethingElse'); 
+9

> [ALERT] Этот ответ не работает. Прочтите ответ 'rfc1484' ниже. – skozz

+1

Возможно, из-за пропущенного $() все. –

+0

Отлично! Элегантный и чистый, спасибо –

0

IMO вы можете хранить эти данные в глобальная переменная. Но лучше использовать еще одно уникальное имя или использовать пространство имен:

MyCompany = {};

...
MyCompany.cachedData = данные;

А также лучше использовать json для этих целей, данные в формате json обычно намного меньше, чем те же данные в формате xml.

+0

+1 для json! – jrharshath

+1

global vars - плохие новости – redsquare

+0

Когда вы используете много глобальных варсов, это плохо, но когда вы их используете, это очень помогает. JQuery использует глобальные вары (по крайней мере, $ и jQuery), ExtJS также использует глобальные вары. – zihotki

0

Я бы предположил, что следует избегать получения больших XML-файлов с сервера: переменная «xml» должна использоваться как кеш , а не как хранилище данных.

В большинстве сценариев можно просмотреть кеш и посмотреть, нужно ли вам делать запрос на сервер для получения требуемых данных. Это сделает ваше приложение легче и быстрее.

cheers, jrh.

0

.get ответы кэшируются по умолчанию. Поэтому вам действительно нужно ничего не делать, чтобы получить желаемые результаты.

63

Вот функция, которая хорошо выполняет работу. Я не мог получить лучший ответ выше, чтобы работать.

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

Затем к нему доступ, создать переменную следующим образом:

var results = $.getValues("url string"); 
+2

Хороший! Я узнал что-то новое :) –

+2

Фактически просто добавление «async: false» может решить множество проблем, с которыми вы столкнетесь. – Rooster

+6

и может создавать множество проблем, таких как замораживание браузера в течение нескольких секунд :) –

15

Вы не должны делать ничего из этого. Я столкнулся с той же проблемой с моим проектом. то, что вы делаете, - это вызов функции внутри обратного вызова с успешным выполнением для сброса глобальной переменной. До тех пор, пока вы установите асинхронный javascript в false, он будет работать правильно. Вот мой код. Надеюсь, поможет.

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; 
} 

Надеюсь, это вам поможет.

+1

бог как ответ для меня: D – Aditzu

+1

Это работает очень хорошо! ТОЛЬКО 1 вещь, если (data == true) необходимо изменить. Это может быть просто пусто. –

+0

Я пытался воссоздать узлы из возвращаемого ответа ajax. Мой скрипт работал бы каждый раз, когда я использовал существующие узлы, но не работал при попытке воссоздать объекты, структурированные из ответа ajax. Это решение сработало для меня. Я не буду исследовать прямо сейчас, но я подозреваю, что асинхронная настройка изменила ситуацию. – IberoMedia

8

Ваша проблема может быть связана не с какой-либо локальной или глобальной областью, но только задержка сервера между выполнением функции «Успех» и временем, когда вы пытаетесь извлечь данные из вашей переменной.

вероятность того, что вы пытаетесь распечатать содержимое переменной до того, как срабатывает функция «успех» ajax.

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

    } 
0

Я знаю, что нить устарела, но я подумал, что кто-то может найти это полезным. Согласно 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; 

поможет получить результат непосредственно в строке. Примечание: .responseText; часть.

32

Это работает для меня:

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; 

Важно отметить: global: false, async:false и, наконец, responseText прикован к $.ajax запросу.

+0

Превосходно! Это работало для меня как прелесть! Качественный товар. – curlyreggie

+0

То же самое здесь ... спасибо. – BlackjacketMack

+1

async: false создаст хаос! Если у вас есть beforeSend с загрузочным gif или что-то еще, async сделает его очень уродливым –

1

В этом тоже. Много ответов, тем не менее, только одна простая правильная, которую я собираюсь предоставить. Ключ должен сделать ваш вызов $ .ajax..sync!

$.ajax({ 
    async: false, ... 
+1

Если вы хотите остановить страницу с огромной нагрузкой .... идти вперед .... – Neal

+1

спасибо за понижение, но эй, я пришел сюда, чтобы найти решение, которое не имело блокировки в его теле и для другие люди, которые могут наткнуться на этот вопрос, мое решение может быть ответом! – stvn

+2

В этом вопросе все обследуются, поэтому я тоже могу это сделать. Начиная с jQuery 1.8, 'async: false' устарел, и всегда есть лучший способ обработать ваш код, чем синхронизировать ваши запросы. –

2

Я действительно боролся с получением результатов jQuery ajax в своих переменных на этапе «document.ready» событий.

ajax jQuery будет загружаться в мои переменные, когда пользователь запускает событие «onchange» окна выбора после того, как страница уже загружена, но данные не будут передавать переменные при первой загрузке страницы.

Я пробовал много, много и много разных методов, но в конце концов, это был метод Чарльза Гильберта, который работал лучше всего для меня.

Шляпы к Чарльзу Гильберту! Используя его ответ, я могу получить данные в свои переменные, даже когда моя страница загружается первой.

Вот пример рабочего сценария:

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"); 
5
 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'); 

Это работает !!!

7

Вы можете найти его проще хранения значений отклика в элементе DOM, так как они доступны по всему миру:

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

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

Это имеет то преимущество, не нуждаясь установить асинхронной ложь. Ясно, зависит ли это от того, чего вы пытаетесь достичь.

+1

Так просто! Это сработало для меня, хотя вместо того, чтобы устанавливать значение ввода, я использовал метод .data() jQuery для хранения JSON. – Anthony

Смежные вопросы