2012-05-20 4 views
0

у меня есть вызов Ajax, и это работает хорошо, когда я называю новый АЯКС вызов внутри старой, я получил ошибку в первом вызовевызова два Аякс функции внутри друг друг

только один Аякс вызова

$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE",function(data){ 
      var concepts = data[0]; 
      var relations = data[1]; 
      for(var i = 0 ; i < concepts.length ; i++){ 
       var IOS = ''; 
       $("#ioAddRelatedConcepts").append('<p>\n\ 
        connect to\n\ 
        <span class="ioAddConcept">'+concepts[i]+'</span>\n\ 
        with\n\ 
        <span class="ioAddRelation">'+relations[i]+'</span>\n\ 
        <select name ="concetedIOs[]" class="TypeSelector">\n\ 
        '+IOS+'</select>\n\ 
        <span class="errorMessage"></span>\n\ 
        <a href="#" class="removeA" id="aioRemoveIO">remove</a>\n\ 
       </p>\n\ 
        <p>'); 
      } 
     }); 

после добавления этого вызова Ajax

$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE",function(data){ 
      var concepts = data[0]; 
      var relations = data[1]; 
      for(var i = 0 ; i < concepts.length ; i++){ 
       $.getJSON("http://localhost/Mar7ba/InformationObject/getIOsForConcept/"+concepts[i]+"/TRUE",function(data1){ 
        var IOS = ''; 
        $("#ioAddRelatedConcepts").append('<p>\n\ 
        connect to\n\ 
        <span class="ioAddConcept">'+concepts[i]+'</span>\n\ 
        with\n\ 
        <span class="ioAddRelation">'+relations[i]+'</span>\n\ 
        <select name ="concetedIOs[]" class="TypeSelector">\n\ 
        '+IOS+'</select>\n\ 
        <span class="errorMessage"></span>\n\ 
        <a href="#" class="removeA" id="aioRemoveIO">remove</a>\n\ 
       </p>\n\ 
        <p>'); 
       }); 
      } 
     }); 

после этого понятие [I] и отношение [I] будет как undifined и data1.le ngth всегда нуль и это второй PHP код AJAX

public function getIOsForConcept($conceptName, $AJAX) { 
     if ($AJAX) { 
      $results = $this->model->getIOsForConcept($conceptName); 
      $IOs = array(); 
      $i = 0; 
      while ($row = $results->fetch()) { 
       $IOs[$i] = $row['name']; 
       $i++; 
      } 
      return json_encode($IOs); 
     } 
    } 

и я попробовал его и он работает хорошо

+3

Возможно ** ** не рекомендуется делать вызовы в цикле 'for', так как они возвращаются асинхронно, т. Е. Сам цикл будет (почти наверняка) завершен до того, как кто-либо из них вернется, что может усложнить вещи. Если вы хотите, чтобы они происходили последовательно, вы должны вложить их друг в друга. – delicateLatticeworkFever

+0

@ goldilocks, но для каждого значения первого цикла я должен получить данные с сервера, поэтому я помещаю ajax-вызов в цикл любым способом, почему concpetp [i] и отношение [i] не работают после объявления seocnd ajax call – LinCR

+0

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

ответ

3

Причина, по которой concepts[i] и relations[i] не определены в функции обратного вызова внутреннего $.getJSON() - это $.getJSON()aysnchronous, что означает, что весь цикл цикла будет закончен, пока какой-либо из обратных вызовов не возникнет во внутренних вызовах $.getJSON() - поэтому к моменту возникновения этих внутренних обратных вызовов i есть o ne выше максимального индекса массивов concepts и relations.

Чтобы обойти эту проблему можно ввести дополнительное замыкание, чтобы сохранить значения из каждой итерации:

$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE", function(data){ 
    var concepts = data[0]; 
    var relations = data[1]; 
    for(var i = 0 ; i < concepts.length ; i++){ 
     (function(currentConcept, currentRelation) { 
     $.getJSON("http://localhost/Mar7ba/InformationObject/getIOsForConcept/"+currentConcept+"/TRUE" , function(data1){ 
      var IOS = ''; 
      $("#ioAddRelatedConcepts").append('<p>\n\ 
       connect to\n\ 
       <span class="ioAddConcept">'+ currentConcept +'</span>\n\ 
       with\n\ 
       <span class="ioAddRelation">'+ currentRelation +'</span>\n\ 
       <select name ="concetedIOs[]" class="TypeSelector">\n\ 
       '+IOS+'</select>\n\ 
       <span class="errorMessage"></span>\n\ 
       <a href="#" class="removeA" id="aioRemoveIO">remove</a>\n\ 
       </p>\n\ 
       <p>'); 
     }); 
     })(concepts[i], relations[i]); 
    } 
}); 

Анонимная функция Я добавил внутри цикл будет выполняться один раз в итерацию создания отдельных затворов каждый с их собственные currentConcept и currentRelation.

EDIT: Для того, чтобы сделать это действительно очевидно, что я изменился по сравнению с исходной code--

Добавьте следующую строку в качестве первой вещи внутри существующего for цикла:

(function(currentConcept, currentRelation) { 

А потом следующая строка в последнюю очередь, прежде вашего существующего for передачи контура ценой закрытия }:

})(concepts[i], relations[i]); 

И тогда е где-то внутри петли for, где у вас были concepts[i] и relations[i], смените их на currentConcept и currentRelation.

+0

да, человек, спасибо, и сделайте меня понятным проблема хорошая, но, пожалуйста, ур код имеет синтаксическую ошибку, и я не очень хорош в jquery и не могу знать, где не так, mabye an missng закрытие} – LinCR

+0

Извините, я, очевидно, не смог проверить его без остальной части вашего кода. Я думаю, что проблема была дополнительной '}), которую я сейчас удалил. Единственное изменение в вашем коде должно заключаться в добавлении строки сразу после 'for', строки непосредственно перед концом'} '' for', а изменение для использования переменных currentConcept и 'currentRelation' в середине вашего '.append()'. – nnnnnn

+0

ОК, я попробую, но вы правы: 'for (var i = 0; i LinCR

4

Вы не можете использовать переменную цикла (i в вашем случае) внутри функции обратного вызова - она ​​будет иметь какое бы то ни было значение, когда цикл был завершен к моменту активации вашей функции обратного вызова async.

Как вы уже используете JQuery, вы можете также использовать $.each():

$.getJSON(..., function(data) { 

    var concepts = data[0]; 
    var relations = data[1]; 

    $.each(concepts, function(i, value) { 

     // concepts[i] is OK to use now, and is also in "value" 
     // relations[i] is OK to use too 

     $.getJSON(..., function() { 

      // you can still use them here, too! 

     }); 
    }); 
}); 

, который будет гарантировать, что i правильно связан с текущим номером итерации каждый раз.

+0

, я попробую ваш код, – LinCR

+0

это по-прежнему та же ошибка – LinCR

+1

+1. Этот код более аккуратный, чем мой ответ, который сохранил исходный цикл 'for'. Использование '$ .each()' вводит требуемое закрытие и упорядочивает 'for' в одно и то же время. (Хотя обратите внимание, @LinCR, что он работает по той же причине, что и мой.) – nnnnnn

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