2013-11-08 6 views
0

Я прочитал пару других потоков на этом, но, похоже, не может понять его. Я не очень много знаю о Javascript и до сих пор догадывался о моем пути. У меня есть одна функция, запускающая запрос AJAX для получения некоторых строк из базы данных. Затем для каждой строки мне нужно запустить вложенный запрос AJAX и вернуть его значения первой функции. Оба запроса AJAX работают независимо, но я не знаю, как правильно их вложить. Вот что у меня есть:Javascript вложенные запросы AJAX

function updateSummaryVariablesInput(typeId) { 
    if (typeId=='') { 
     document.getElementById('summaryVariables').innerHTML=''; 
     return; 
    } 
    if (window.XMLHttpRequest) { 
     // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp2=new XMLHttpRequest(); 
    } else { 
     // code for IE6, IE5 
     xmlhttp2=new ActiveXObject('Microsoft.XMLHTTP'); 
    } 
    xmlhttp2.onreadystatechange=function() { 
     if (xmlhttp2.readyState==4 && xmlhttp2.status==200) { 
      xmlDoc=xmlhttp2.responseXML; 
      txt='<table>'; 
      x=xmlDoc.getElementsByTagName('row'); 
      for (i=0;i<x.length;i++) { 
       if (x[i].getElementsByTagName('common')[0].childNodes[0].nodeValue < 1) { 
        txt=txt + '<tr><th style=\"width: 150px;\">' + x[i].getElementsByTagName('label')[0].childNodes[0].nodeValue + '</th><td>'; 
        // Select 
        if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'select') { 
         txt=txt + '<select name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\"><option></option>'; 
         myoptions = getSummaryVariableOptions(x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue); 
         //alert(myoptions.length); 
         for (j=0;j<myoptions.length;j++) { 
          txt=txt + '<option value=\"' + myoptions[j] + '\">' + myoptions[j] + '</option>'; 
         } 
         txt=txt + '</select>'; 
        } 
        // Text 
        if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'text') { 
         txt=txt + '<input type=\"text\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\" />'; 
        } 
        txt=txt + '</td></tr>'; 
       } 
      } 
      txt=txt + '</table>'; 
      document.getElementById('summaryVariables').innerHTML=txt; 
     } 
    } 
    xmlhttp2.open('GET','/cgi/new/Ajax/getOutageVariablesByTypeId.php?typeId='+typeId,true); 
    xmlhttp2.send(); 
} 

function getSummaryVariableOptions(variableId) { 
    var options = new Array(); 
    if (window.XMLHttpRequest) { 
     // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp3=new XMLHttpRequest(); 
    } else { 
     // code for IE6, IE5 
     xmlhttp3=new ActiveXObject('Microsoft.XMLHTTP'); 
    } 
    xmlhttp3.onreadystatechange=function() { 
     if (xmlhttp3.readyState==4 && xmlhttp3.status==200) { 
      xmlDoc=xmlhttp3.responseXML; 
      x=xmlDoc.getElementsByTagName('row'); 
      for (i=0;i<x.length;i++) { 
       options[i] = x[i].getElementsByTagName('description')[0].childNodes[0].nodeValue; 
      } 
      alert(options.length); 
     } 
    } 
    xmlhttp3.open('GET','/cgi/new/Ajax/getOutageVariableOptionsByVariableId.php?variableId='+variableId,true); 
    xmlhttp3.send(); 
    //alert(options.length); 
    return options; 
} 

Запуск как есть, я получу предупреждение с действительным номером, например. 5. Если я раскомментирую любую из других функций предупреждения, они будут только выводить 0.

+0

нативный код JavaScript для работы с AJAX делает мои глаза кровоточат :( – Alnitak

+0

Согласовано! Есть ли какой-то другой способ, которым я мог бы делать это? Это PHP генерируется HTML формы, и мне нужно определенные части формы изменяться в зависимости на других опциях, выбранных в форме. – Matt

+0

Большинство людей обычно обрабатывают ajax, используя фреймворк, наиболее популярный jQuery. См. http://api.jquery.com/jQuery.ajax/ –

ответ

1

Проблема в том, что вы пытаетесь получить доступ к возвращаемому значению со второго вызова ajax, как если бы он был синхронным, а это не так.

Так что, когда вы звоните getSummaryVariableOptions внутри первого вызова Ajax, вам нужно сделать что-то вроде:

getSummaryVariableOptions(...., function (myoptions) { 
    alert(myoptions.length); // now you have what you need here 
    ..... /// put the reset of the code that depende on myoptions here 
}); 

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

function getSummaryVariableOptions(variableId, callback) { 
    ... inside the readystate === 4 ... 
    callback(options); 
} 

При вызове getSummaryVariableOptions он начинает вызов Ajax и немедленно возвращается, так что вы должны ждать, пока вызов не завершится, а затем получить перезвонил с данными вызова. Вы не можете сделать var myoptions = getSummaryVariableOptions(..)

EDIT:

Подход на основе JQuery будет выглядеть следующим образом:

$.getJSON(url1, function (res1) { 
    $.getJSON(url2, function (res2) { 
    // now you have both res 1 and res 2 to process here... 
    }); 
}); 
+0

Так определить getSummaryVariableOptions в updateSummaryVariablesInput? Как вы, вероятно, можете сказать, что я действительно не получаю весь этот «синхронный» бизнес: p Просто увидел ваше редактирование, я попробую это и посмотрю, как я пойду, спасибо. – Matt

+0

см., Если редактирование помогает прояснить проблему и как ее решить. – Jaime

+0

Извините, я все еще не совсем уверен, что делать. Можете ли вы опустить его немного больше? Благодаря! – Matt

0

Вложенные запросы Ajax нужен массив для хранения каждого запроса и OnComplete журнала ошибок ..

https://stackoverflow.com/a/18728553/2450730

Простое решение выполняет последовательный сценарий ajax .. (используется xhr2 & JSON) также нуждается в проверке ошибок somemore .. но это дает вам представление о том, как это сделать.

var mainListArray, 
Length, 
Current; 

function ajax(a,b,c){c=new XMLHttpRequest;c.open('GET',a);c.onload=b;c.send()}; 

function loadmain(){ 
ajax('mainList.php',seq) 
} 

function seq(){ 
mainListArray=JSON.parse(this.response); 
Length=mainListArray.length; 
Current=0; 
next(); 
} 

function next(){ 
ajax('Detail.php?id='+mainListArray[Current].id,add); 
Current++; 
} 

function add(){ 
// do something with detailed data 
if(Current<Length){ 
    next(); 
}else{ 
    //everything loaded. 
} 
} 

window.onload=loadmain; 

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

функция Аякса объяснил

https://stackoverflow.com/a/18309057/2450730

и вот графический пример того, как работают последовательные функции.

http://jsfiddle.net/4eujG/

1

Почти получил там следующий ответ от Хайма. Все еще была проблема, когда getSummaryVariableOptions был фактически асинхронным вызовом ajax, означающим updateSummaryVariablesInput, законченным задолго до того, как результаты getSummaryVariableOptions втянуты. Это привело к добавлению тегов к txt ПОСЛЕ закрытия тега. Shea внесла изменения, чтобы хранить теги опций в массиве, а затем вставлять их позже, используя innerHtml. Спасибо, Ши!

var getQueue = []; 

function updateSummaryVariablesInput(typeId) { 
    if (typeId=='') { 
     document.getElementById('summaryVariables').innerHTML=''; 
     return; 
    } 
    if (window.XMLHttpRequest) { 
     // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp2=new XMLHttpRequest(); 
    } else { 
     // code for IE6, IE5 
     xmlhttp2=new ActiveXObject('Microsoft.XMLHTTP'); 
    } 
    xmlhttp2.onreadystatechange=function() { 
     if (xmlhttp2.readyState==4 && xmlhttp2.status==200) { 
      xmlDoc=xmlhttp2.responseXML; 
      txt='<table>'; 
      x=xmlDoc.getElementsByTagName('row'); 
      for (i=0;i<x.length;i++) { 
       if (x[i].getElementsByTagName('common')[0].childNodes[0].nodeValue < 1) { 
        txt=txt + '<tr><th style=\"width: 150px;\">' + x[i].getElementsByTagName('label')[0].childNodes[0].nodeValue + '</th><td>'; 
        // Select 
        if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'select') { 
         txt=txt + '<select id=\"' + x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue + '\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\"><option></option></select>'; 
         // Add it to a queue, to do it later 
         getQueue.push(x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue); 
        } 
        // Text 
        if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'text') { 
         txt=txt + '<input type=\"text\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\" />'; 
        } 
        txt=txt + '</td></tr>'; 
       } 
      } 
      txt=txt + '</table>'; 
      document.getElementById('summaryVariables').innerHTML=txt; 
      for (var gsi = 0; gsi < getQueue.length; ++gsi) { 
       getSummaryVariableOptions(getQueue[gsi], function (myoptions, parentId) { 
        var parentSelect = document.getElementById(parentId), 
         optionsTxt = ''; 
        for (j=0;j<myoptions.length;j++) { 
         optionsTxt=optionsTxt + '<option value=\"' + myoptions[j] + '\">' + myoptions[j] + '</option>'; 
        } 
        parentSelect.innerHTML = optionsTxt; 
       }); 
      } 
     } 
    } 
    xmlhttp2.open('GET','/cgi/new/Ajax/getOutageVariablesByTypeId.php?typeId='+typeId,true); 
    xmlhttp2.send(); 
} 

function getSummaryVariableOptions(variableId, callback) { 
    var options = new Array(); 
    if (window.XMLHttpRequest) { 
     // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp3=new XMLHttpRequest(); 
    } else { 
     // code for IE6, IE5 
     xmlhttp3=new ActiveXObject('Microsoft.XMLHTTP'); 
    } 
    xmlhttp3.onreadystatechange=function() { 
     if (xmlhttp3.readyState==4 && xmlhttp3.status==200) { 
      xmlDoc=xmlhttp3.responseXML; 
      x=xmlDoc.getElementsByTagName('row'); 
      for (i=0;i<x.length;i++) { 
       options[i] = x[i].getElementsByTagName('description')[0].childNodes[0].nodeValue; 
      } 
      // Revised to send variableId to callback 
      callback(options, variableId); 
      //alert(options.length); 
     } 
    } 
    xmlhttp3.open('GET','/cgi/new/Ajax/getOutageVariableOptionsByVariableId.php?variableId='+variableId,true); 
    xmlhttp3.send(); 
    //alert(options.length); 
    //return options; 
} 
+0

Добро пожаловать! : D – Shea

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