2014-11-13 3 views
0

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

Теперь я хочу, чтобы вызов ajax был загружен, установите результат json как переменную, доступную нескольким функциям. Я думал, что бы что-то вроде этого:

window.onload = function() { 

    var myJsonData = function() { 
     var request = new XMLHttpRequest(); 
     request.open("GET", "/json/someJsonData.json", true); 
     request.setRequestHeader("content-type", "application/json"); 
     request.send(null); 
     request.onreadystatechange = function() { 
      if (request.readyState === 4) { 
       if (request.status === 200) { 
        var myJsonString = JSON.parse(request.responseText); 
        var myJsonArray = myJsonString["Projects"]; 
        return myJsonArray; 
       } 
      } 
     } // onreadystatechange 
    } // var myJsonData 

    myJsonData(); // * 
    console.log("myJsonArray: " + myJsonArray); // undefined 

Или:

window.onload = function() { 
    myJsonData(); 
} 

function myJsonData() { 
    var request = new XMLHttpRequest(); 
    request.open("GET", "/json/someJsonData.json", true); 
    request.setRequestHeader("content-type", "application/json"); 
    request.send(null); 
    request.onreadystatechange = function() { 
     if (request.readyState === 4) { 
      if (request.status === 200) { 
       var myJsonString = JSON.parse(request.responseText); 
       var myJsonArray = myJsonString["Projects"]; 
       alert("you are here (myJsonArray defined)"); 
       alert("myJsonArray: " + myJsonArray); 
       console.log("myJsonArray: " + myJsonArray); 
       return myJsonArray; 
      } 
     } 
    } // onreadystatechange 
} // var myJsonData 

console.log("myJsonArray: " + myJsonArray); // undefined 

Или:

window.onload = myJsonData; 
// etc. 

Конечно myJsonArray не определен либо образом. Мне явно не хватает чего-то фундаментального в том, как это сделать (или это вообще плохая идея?). Есть ли способ передать результат в качестве обратного вызова при вызове ajax-запроса при загрузке?

Может кто-нибудь, пожалуйста, просветит меня о том, как исходить из этого, возможно, скелетный пример? (Приписка еще сосредоточив внимание на родных JS, не JQuery)

Большое спасибо заранее,

SVS

+0

асинхронной/запрос синхронизации ... прочитать [здесь] (http://www.w3schools.com/ajax/ajax_xmlhttprequest_send. asp), установите последний параметр в 'false'. – skobaljic

+0

@skobaljic Спасибо. Я немного удивлен, увидев предложение пойти на синхронизацию, кажется, противоречит всему, что я читал о синхронизации/асинхронном режиме. Даже страница, на которую вы ссылались, говорит: «Использование async = false не рекомендуется». Будет ли более целесообразным или более традиционным изменение структуры? – user1613163

+0

Вы можете использовать async, но только после того, как вы получите ответ json, вы можете вызвать функцию «init» приложения, определить переменные приложения и т. Д. Поскольку эти данные важны, вы можете начать загрузку с самого начала на странице, ожидая, что данные будут доступный на главной странице. Во время загрузки вы можете поместить загрузчик. Но то, что вы не можете сделать, это: return 'myJsonArray' для' function myJsonData() 'внутри асинхронного вызова xhr. – skobaljic

ответ

1

Есть некоторые вещи неправильно в коде. Сначала myJsonArray является локальным для функции myJsonData(). Вы должны определить его глобально. Во-вторых, запрос ajax является асинхронным. Перед тем, как работать с ним, вы должны дождаться результата. Вот рабочий пример, основанный на вашем коде:

var myJsonArray; //Globally defined 
     window.onload = function() { 

      var outputData = function() { 
       console.log(myJsonArray); 
      } 

      var myJsonData = function() { 
       var request = new XMLHttpRequest(); 
       request.open("GET", "someJsonData.json", true); 
       request.send(null); 
       request.onreadystatechange = function() { 
        if (request.readyState === 4) { 
         if (request.status === 200) { 

          myJsonArray = JSON.parse(request.responseText); 
          outputData(); //Ouput when result is received 
         } 
        } 

       } // onreadystatechange 


      } // var myJsonData 

      myJsonData(); // * 

     } 
+0

Спасибо, Алекс. Я думал, что мне следует избегать использования глобальной переменной, но в любом случае кажется, что я использую window.onload или (function() {...})(), требуется некоторая версия обратного вызова в ajax. Я думаю, что раньше я отсутствовал, так это то, что это сводится к проблеме сферы охвата; что любая функция, которую я на самом деле представляю на странице, должна быть либо дочерним, либо дочерним элементом функции ajax. Ура! svs – user1613163

1

Использование Javascript может решить вашу проблему. Promises are native to ES6, хотя, очевидно, browser support еще не совсем там. Несмотря на это, вот как вы могли бы реализовать свой код с обещаниями:

window.onload = function() { 
    myJsonData().then(function (result) { 
     console.log("myJsonArray: " + result); 
     alert(result.one); 
     // do something else here 
    }); 
} 

function myJsonData() { 
    return new Promise(function (resolve, reject) { 
     var request = new XMLHttpRequest(); 
     request.open("GET", "http://echo.jsontest.com/key/value/one/two", true); 
     request.setRequestHeader("content-type", "application/json"); 
     request.send(null); 
     request.onreadystatechange = function() { 
      if (request.readyState === 4) { 
       if (request.status === 200) { 
        var myJsonString = JSON.parse(request.responseText); 
        //var myJsonArray = myJsonString["Projects"]; 
        resolve(myJsonString); 
       } 
      } 
     } // onreadystatechange 
    }); 
} // var myJsonData 

Here is a jsfiddle

+0

Спасибо. Это не первое, что я слышал о обещаниях в контексте асинхронных/обратных вопросов.Мне кажется, мне нужно работать с callbacks (и js101 в целом), прежде чем перейти к смелому новому миру ES6. Но я доберусь туда! Спасибо! – user1613163