JavaScript:从JSON获取数据

3
基础知识:我有一个HTML表格。我希望在不重新加载页面的情况下向表格中添加行。我创建了一个servlet,每当单击“添加”按钮时,它返回我要添加到表格中的值。
问题:我可以很好地动态添加行到表格中。问题是如何将数据从servlet中获取。这个servlet非常简单。发送三个值并返回一个JSON,其中包含新行的值。我已经测试过了,它工作得很好。问题是我用来保存值的变量在$.getJSON()函数设置好后不会传递到函数外。我对javascript没有太多经验,所以我不确定变量声明的优先级,但有一件事是肯定的,我的变量一旦内部函数完成就不再保留它们的值了。任何见解将不胜感激。
function addPerson()
{
    var e = document.getElementById("newperson");
    var personid = e.options[e.selectedIndex].value;
    var roleid = e.options[e.selectedIndex].value;
    var r = document.getElementById("newrole");
    var roleid = r.options[r.selectedIndex].value;
    var o = document.getElementById("thisorganizationid");
    var orgid = o.options[o.selectedIndex].value;

    var personName = "";
    var orgName = "";
    var roleName = "";

    $.getJSON("GetPersonRole",{
        personid: personid,
        roleid: roleid,
        orgid: orgid,
      }, function(json) {
          personName = json.Person;
          orgName = json.Organization;
          roleName = json.Role;

          alert('person: ' + personName + '  role: ' + roleName); //They all display properly here
      });

    var table = document.getElementById("PersonTable");
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);

    var cell1 = row.insertCell(0);
    cell1.innerHTML = orgName;

    var cell2 = row.insertCell(1);
    cell2.innerHTML = personName;

    var cell3 = row.insertCell(2);
    cell3.innerHTML = roleName;

    var cell4 = row.insertCell(3);
    cell4.innerHTML = "adding";

    document.getElementById('addingPerson').innerHTML = addString;
}
4个回答

3

getJSON() 是一个异步函数。如果你不确定这是什么意思,我建议你阅读一篇关于异步JS编程的教程。

对于你的问题,简单的答案是:你正在尝试在getJSON() 方法完成之前将变量的值分配给DOM元素。这里有一个快速修复方法(请参阅注释以获取更多说明):

...

$.getJSON("GetPersonRole",{
        personid: personid,
        roleid: roleid,
        orgid: orgid,
      }, function(json) { //Executes when the asynchronous call is complete
          personName = json.Person;
          orgName = json.Organization;
          roleName = json.Role;

          UpdateMyPage(personName, orgName, roleName);
});

//Most likely will execute before the asynchronous call is complete
alert("HERE");

function UpdateMyPage(personName, orgName, roleName) {
    var table = document.getElementById("PersonTable");
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);

    var cell1 = row.insertCell(0);
    cell1.innerHTML = orgName;

    var cell2 = row.insertCell(1);
    cell2.innerHTML = personName;

    var cell3 = row.insertCell(2);
    cell3.innerHTML = roleName;

    var cell4 = row.insertCell(3);
    cell4.innerHTML = "adding";

    document.getElementById('addingPerson').innerHTML = addString;   
}

1

您的回调函数:

    $.getJSON("GetPersonRole",{
        personid: personid,
        roleid: roleid,
        orgid: orgid,
      }, function(json) {
          personName = json.Person;
          orgName = json.Organization;
          roleName = json.Role;

          alert('person: ' + personName + '  role: ' + roleName); //They all display properly here
 });

当 AJAX 调用返回时执行。这意味着在它们被添加到表格之后,您的变量才会设置为新值。

您的代码应该像这样:

function addPerson()
{
    var e = document.getElementById("newperson");
    var personid = e.options[e.selectedIndex].value;
    var roleid = e.options[e.selectedIndex].value;
    var r = document.getElementById("newrole");
    var roleid = r.options[r.selectedIndex].value;
    var o = document.getElementById("thisorganizationid");
    var orgid = o.options[o.selectedIndex].value;

    var personName = "";
    var orgName = "";
    var roleName = "";

    $.getJSON("GetPersonRole",{
        personid: personid,
        roleid: roleid,
        orgid: orgid,
      }, function(json) {
          personName = json.Person;
          orgName = json.Organization;
          roleName = json.Role;

          alert('person: ' + personName + '  role: ' + roleName); //They all display properly here

          var table = document.getElementById("PersonTable");
          var rowCount = table.rows.length;
          var row = table.insertRow(rowCount);

          var cell1 = row.insertCell(0);
          cell1.innerHTML = orgName;

          var cell2 = row.insertCell(1);
          cell2.innerHTML = personName;

          var cell3 = row.insertCell(2);
          cell3.innerHTML = roleName;

          var cell4 = row.insertCell(3);
          cell4.innerHTML = "adding";

          document.getElementById('addingPerson').innerHTML = addString;
     });
}

谢谢,你说得完全正确。现在我知道我的错误在哪里了。将剩余代码包含在getJSON中会导致整个块以某种方式执行。非常感谢! - sankofamusician

0

看起来行是在服务器返回值之前添加的。我会创建一个addRow()函数,并在成功时调用它:

function addRow(json){
    // include all code after the getJSON method above...
    var cell1 = row.insertCell(0);
    cell1.innerHTML = json.Organization;

    var cell2 = row.insertCell(1);
    cell2.innerHTML = json.Person;

    // etc...
}

然后你需要做:

$.getJSON("GetPersonRole",{
    personid: personid,
    roleid: roleid,
    orgid: orgid,
  }, addRow);

-5

你的变量是在函数范围内定义的。如果你像这样全局定义它们,那么你应该能够在其他地方访问它们:

var personName = "";
var orgName = "";
var roleName = "";
function addPerson()
    {
        ...

etc...

他也在函数内部使用它们,格式有点混乱,导致看起来好像addPerson函数已经结束了。 - BNL
那样做是无法解决问题的。如果你仔细看,你会发现在 AJAX 回调执行之前,表格已经被更新了。 - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接