0

我正在编写一个简单的 JavaScript 表单,它是一个设备列表,每个设备旁边都有一个按钮,该按钮应将您带到一个文本字段,您可以在其中编辑有关设备的信息。相反,所有按钮都会将您带到列表中最后一个设备的信息。这是我创建列表的片段:

for(var i in portal.clients){
  var row = document.createElement('tr');
  var cell2 = document.createElement('td');
  var button = document.createElement('button')
  var title = document.createTextNode("Edit Config")
  button.appendChild(title)
  button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
  cell2.appendChild(button)
  row.appendChild(button)

  var cell1 = document.createElement('td');
  var client = document.createTextNode(portal.clients[i].info.description.name)
  cell1.appendChild(client)
  row.appendChild(cell1)
  table.appendChild(row);
}

我认为问题是函数声明i中的onClick函数在单击按钮时被评估,而不是在函数声明时像我的意思那样。有没有一种方法可以在声明函数时强制对变量进行评估?还是我应该使用其他方法将客户端索引传递给函数?

4

3 回答 3

4

任何时候你想i在回调中使用你的迭代变量(即在你的循环完成之前不会被评估的东西)你需要在一个新的范围内捕获变量。

for(var i in portal.clients){
    (function(i){
        // do something later with i
    })(i);
}

这里有很多关于 JavaScript 范围的讨论。我强烈建议您阅读它,因为以任何重要的方式理解 JavaScript 都是必不可少的。

于 2012-10-22T18:52:17.620 回答
1

您需要创建一个新的范围,其中i每个迭代都有一个副本。在您提供的代码中,您可以通过编写一个立即运行并返回您想要与附加的新范围中的变量一起使用的实际函数的函数来创建一个新范围:

for(var i in portal.clients) {
  var row = document.createElement('tr');
  var cell2 = document.createElement('td');
  var button = document.createElement('button')
  var title = document.createTextNode("Edit Config")
  button.appendChild(title)
  button.onclick = (function(i){return function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}; })(i);
  cell2.appendChild(button)
  row.appendChild(button)

  var cell1 = document.createElement('td');
  var client = document.createTextNode(portal.clients[i].info.description.name)
  cell1.appendChild(client)
  row.appendChild(cell1)
  table.appendChild(row);
}
于 2012-10-22T18:55:14.520 回答
0

您可以通过将循环置于自执行函数中来绕过它。未经测试的例子:

for(var i in portal.clients){
  (function (i) {
    var row = document.createElement('tr');
    var cell2 = document.createElement('td');
    var button = document.createElement('button')
    var title = document.createTextNode("Edit Config")
    button.appendChild(title)
    button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
    cell2.appendChild(button)
    row.appendChild(button)

    var cell1 = document.createElement('td');
    var client = document.createTextNode(portal.clients[i].info.description.name)
    cell1.appendChild(client)
    row.appendChild(cell1)
    table.appendChild(row);
  })(i);
}
于 2012-10-22T18:51:00.600 回答