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

問題は、関数が意図したように宣言されたときではなく、ボタンがクリックされたときionClick関数宣言の が評価されることだと思います。関数の宣言時に変数を強制的に評価する方法はありますか? または、クライアント インデックスを関数に渡すために使用する必要がある他の方法はありますか?

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 に答える