2

私のコードは次のようになります。

if (ACTIVETICKETS.length > 0) 
{
    for (var m in  ACTIVETICKETS) 
    {
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    } // for loop ends here
}

これを実行している間、m の最後の反復のみを取得しています。ACTIVETICKETS 配列の全長は 16 です。したがって、16 回入力されたのは 15 だけです。

4

3 に答える 3

2

以下のコードは機能するはずですが、上でコメントしたように、閉鎖について読んで理由がわかるようにしてください。

    if (ACTIVETICKETS.length > 0) {
      for (var m in  ACTIVETICKETS) {
        (function(x) {
          if (ACTIVETICKETS.hasOwnProperty(x)) {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[x].location.x, ACTIVETICKETS[x].location.y));
              createHtmlForPopUp(x, function(data){
                console.log(x);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);
              });
          }
        })(m);
      } // for loop ends here
    }
于 2013-07-05T15:00:18.517 に答える
1

あなたが抱えている問題は、m の値が、コールバックが呼び出されるまでに、ループの終わりの値になることです。解決策は、すぐに呼び出される関数の変数の値として設定することで、この値を保護することです。

for (var m in  ACTIVETICKETS) {
   (function(m){
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    })(m);
 } // for loop ends here

これは、JavaScript にはブロック スコープがなく、関数が呼び出されたときにのみ新しい変数スコープを作成するためです。

上記のインライン関数の代わりに、名前付き関数で同じ手法を使用できます。

function makeTicket(m){
  if (ACTIVETICKETS.hasOwnProperty(m)) 
  {
        var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
        createHtmlForPopUp(m, function(data)
        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        });
    }
}

次に、これを行います:

for (var m in  ACTIVETICKETS) {
    makeTicket(m)
} // for loop ends here

for-in補足として、配列で列挙を使用せず、むしろ典型的なループを使用する非常に説得力のある理由がforあり、外側の if テストは必要ないため、それを削除して実行することができます

for (var m =0; m<ACTIVETICKETS.length; m++) {
    makeTicket(m)
}
于 2013-07-05T15:00:29.863 に答える
0

コールバック関数でアクセスするすべての変数に対してクロージャーを作成する必要があります。

    createHtmlForPopUp(m, (function (m, data, marker) {
        return function(data)

        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        }
    })(m, data, marker));
于 2013-07-05T15:01:02.797 に答える