0

Webクラスのプレゼンテーション用のjQueryサンプルを作成しています。演習として行ったJavascriptプログラムをjQueryに変換しようとしています(AJAXなどの便利な部分用)。これまでのところ、すべてが正常に機能しています。唯一のこと:非同期AJAXを介して選択した要素にオプションを設定する方法がわかりません。

これがプログラムのスクリーンショットなので、すべてを説明する必要はありません:http: //imageshack.us/a/img829/5475/tableaui.png

すべてのセルはテキストを含む入力要素であり、すべての変更はAJAXを介して保存されます。最後の行は、新しい行を追加するためのものです。追加するときに、すべての要素が1つずつ作成された行(table.appendChild(tr)を使用)を追加します。select(最初は空で、コンテンツはDBから抽出されます)を除いて、すべてがそこで機能します。ここにいくつかのコードがあります(ajaxが私のデータがDBに挿入されたことを確認した後に呼び出される関数addLine内):

input = document.createElement('select');
input.setAttribute('id', 'ID'+no_ligne+'_'+noms_champs[compteur]);
input.setAttribute('name', 'ID'+no_ligne+'_'+noms_champs[compteur]);
input.innerHTML = ajaxRequest('contenu_select', Array(no_ligne, valeurs[noms_champs[compteur]], noms_champs[compteur]));

ajaxRequestは次のとおりです。

function ajaxRequest(action, data, ligneModifie, champModifie)
{
var AJAX_Controller = 'exer_7_carnet_formulaire.php';
var post_data = resultat_ajax = "";

// Set the posted data
if(action == 'update') {
    //stuff
}
else if(action == 'insert') {
    //stuff
}
else if(action == 'contenu_select') {
    post_data += "noLigne="    + data[0] +
                 "&selected="  + data[1] +
                 "&type="      + data[2];
}
else {
    post_data = null;
}
// Send the request
var jqxhr = $.ajax({
    type: "POST",
    url: AJAX_Controller+'?ajax=1&action='+action,
    data: post_data,
    success: function(reponse) {
        resultat_ajax = processResponse(reponse, data, action);
    }
});
return resultat_ajax;
}

gererReponseは、すべてのオプションの文字列を返します(動作が確認されました)。問題は、リクエストが終了する前にreturnを実行するため、空の文字列を返すことです(resultat_ajaxがまだ定義されていないため)。setTimeoutで確認したところ、変数は1秒後に期待値になりました。

私の質問は:この場合、どのように選択を設定できますか?以前に作成した他のバージョン(jQueryなし)は、ajaxRequest関数を除いてまったく同じコードで、魅力のように機能しました。これは、代わりにそこにあったjQueryのない関数で、機能しています(期待されるオプションを返します):

function ajaxRequest(action, data, ligneModifie, champModifie) 
{
// Variables
var ReqTerminee = 4;
var ReponseOK_Local = 0; 
var ReponseOK_Remote = 200;
var AJAX_Controller = 'exer_7_carnet_formulaire.php';
var xhr = getXMLHttpRequest();
var post_data = typeDeContenu = resultat_final = "";

// Monitoring request state
xhr.onreadystatechange = function() {
    if (xhr.readyState == ReqTerminee)
        if (xhr.status == ReponseOK_Local || xhr.status == ReponseOK_Remote)
            resultat_final = gererReponse(xhr.responseText, data, action); // Here is the interesting part, this actually works and returns the right value.
        else
            alert("Code d'erreur: " + xhr.status);
};

// Sets the posted data
if(action == 'update')
{
    // blahblah
}
else if(action == 'insert')
{
    //blahblah
}
else if(action == 'contenu_select')
{
    post_data += "noLigne="    + data[0] +
                 "&selected="  + data[1] +
                 "&type="      + data[2];
}
else
{
    post_data = null;
}

// Sends the request
xhr.open("POST", AJAX_Controller+'?ajax=1&action='+action, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(post_data);

return resultat_final;
}

単純なJavascriptで得られるのと同じ結果を強力なjQueryで得られないことに少しがっかりしています:/どうすれば良い戻り値を得ることができるか考えていますか?

よろしくお願いします。

サム

4

1 に答える 1

1

問題は、純粋なJSで同期リクエストを使用していることです。これは、次の行でfalseに設定された3番目のパラメーターによって指定されます。

xhr.open("POST", AJAX_Controller+'?ajax=1&action='+action, false);

したがって、この場合、ブラウザは次の行で要求が行われるまで待機しています。

xhr.send(post_data);

そして、onreadystatechangeハンドラーを実行し、その後にのみreturn実行されます。

jQueryには同じオプションがあります(async:false追加を参照):

$.ajax({
    type: "POST",
    url: AJAX_Controller+'?ajax=1&action='+action,
    async:false,
    data: post_data,
    success: function(reponse) {
        resultat_ajax = processResponse(reponse, data, action);
    }
});

しかし-そうしないでください。JSは常にシングルスレッドで実行され、同期リクエストはページ全体をフリーズします。ユーザーは満足しません)。それを行う正しい方法は、次のものを置き換えることです。

input = document.createElement('select');
input.setAttribute('id', 'ID'+no_ligne+'_'+noms_champs[compteur]);
input.setAttribute('name', 'ID'+no_ligne+'_'+noms_champs[compteur]);
input.innerHTML = ajaxRequest('contenu_select', Array(no_ligne, valeurs[noms_champs[compteur]], noms_champs[compteur]));

$.ajax({
        type: "POST",
        url: AJAX_Controller+'?ajax=1&action='+action,
        async:false,
        data: post_data,
        success: function(reponse) {
            resultat_ajax = processResponse(reponse, data, action);
            input = document.createElement('select');
            input.setAttribute('id', 'ID'+no_ligne+'_'+noms_champs[compteur]);
            input.setAttribute('name', 'ID'+no_ligne+'_'+noms_champs[compteur]);
            input.innerHTML = resultat_ajax;
        }
    });

もちろん、あなたは通過する必要がありますno_lignenoms_champsそしてcompteurajaxRequest

于 2012-10-01T21:43:43.763 に答える