0

我正在为我的 Web 类中的演示文稿创建一个 jQuery 示例。我正在尝试将我们作为练习所做的 Javascript 程序转换为 jQuery(对于有用的部分,如 AJAX)。到目前为止一切顺利,一切正常。唯一的事情:我不知道如何通过异步 AJAX 使用选项填充选择元素。

这是程序的截图,所以我不必解释一切:http: //imageshack.us/a/img829/5475/tableaui.png

所有的单元格都是输入元素,里面有文本,每次修改都通过 AJAX 保存。最后一行用于添加新行。添加后,我添加行(带有 table.appendChild(tr) ),其中包含一个一个创建的所有元素。除了选择(一开始是空的,它们的内容是从数据库中提取的)之外,一切都在那里工作。这是一些代码(在函数 addLine 内,在 ajax 确认我的数据已插入数据库后调用):

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 返回我所有选项的字符串(确认工作)。问题是:它在请求完成之前执行返回,所以它返回一个空字符串(因为尚未定义 resultat_ajax)。我用 setTimeout 确认,然后变量在一秒钟后具有预期值。

我的问题是:在这种情况下如何填充我的选择?我之前创建的另一个版本(没有 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;
}

我有点失望,我无法使用强大的 jQuery 获得与使用简单 Javascript 获得的结果相同的结果:/您知道如何设法获得良好的返回值吗?

在此先感谢,任何帮助将不胜感激!

山姆

4

1 回答 1

1

您的问题是在纯 JS 中您使用的是同步请求。在此行中由第三个参数指定为 false:

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_ligne,noms_champscompteur进入ajaxRequest

于 2012-10-01T21:43:43.763 回答