0

私は ajax 呼び出しを持っていますが、うまく機能します。古い ajax 呼び出し内で新しい ajax 呼び出しを呼び出すと、最初の呼び出しでエラーが発生しました

たった1回の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.length は常に null になり、これは ajax の 2 番目の php コードです。

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

そして私はそれを試しました、そしてそれはうまくいきます

4

2 に答える 2

4

コールバック関数内でループ変数(iあなたの場合)を使用することはできません-非同期コールバック関数が呼び出されるまでにループが終了したときの値は何でもあります。

すでに 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、毎回現在の反復回数に正しくバインドされます。

于 2012-05-20T11:17:50.353 に答える
3

内部関数のコールバック関数内でconcepts[i]とが定義されていない理由はaysnchronousであるためです。これは、内部呼び出しでコールバックが発生する前に for ループ全体の実行が終了していることを意味します。したがって、これらの内部コールバックが発生するまでには、および配列の最大インデックスよりも 1 つ大きくなります。relations[i]$.getJSON()$.getJSON()$.getJSON()iconceptsrelations

これを回避するには、追加のクロージャーを導入して、各反復からの値を保持できます。

$.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]);
   }
});

for ループ内に追加した無名関数は、反復ごとに 1 回実行され、それぞれ独自のcurrentConceptandを持つ個別のクロージャーを作成しcurrentRelationます。

編集:元のコードと比較して私が変更したことを本当に明確にするために--

既存のforループ内の最初のものとして次の行を追加します。

   (function(currentConcept, currentRelation) {

次に、既存のforループを閉じる前の最後の行として次の行を追加し}ます。

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

そして、forあなたが持っていたループ内のどこでもconcepts[i]and にrelations[i]変更しcurrentConceptますcurrentRelation

于 2012-05-20T11:17:38.310 に答える