2

Googleマップで作業すると、次のコードがあります:

var tileNames = ["base", "parking", "access"];
var mapType = {};

for (var i = 0; i < tileNames.length; i++) {
    var tileOptions = {
    getTileUrl: function(coord, zoom) {
        return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
    },
    tileSize: new google.maps.Size(256, 256)
    };
mapType[tileNames[i]] = new google.maps.ImageMapType(tileOptions);
};

私の問題は次のとおりです。「getTileUrl」関数の「tileNames [i]」は、関数の実行時に未定義です。ただし、「tileNames」配列は、ここで「mapType」オブジェクトを定義する際にのみ使用することを意図しているため、関数に渡される「coord」および「zoom」変数とは異なり、「tileNames[ i]" を使用して、関数のその部分を定義します。したがって、理想的には、mapType.parking に割り当てられる関数は次のようになります...

function(coord, zoom) {
    return "/maps/tiles/tilesparking/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
};

...関数がコードの最初の部分で定義された後。変数/配列の値を取得し、それを使用して関数を静的に定義しながら、他の2つの変数を変数として維持する方法はありますか?


編集:以下のさまざまな回答を見ると、これまでに達成できた最高のものは次のとおりです。より一般的なシナリオではバインドが理想的なアプローチかもしれませんが、この特定のケースでは、「getTileUrl:」は明らかに特定の構文を必要としており、定義された関数の周りにバインドを配置すると、マップでエラーが発生します。KGZM の提案を試すと、IE8 以下ではなく、最新のすべてで機能します。

var tileNames = ["beloit", "parking", "access_p"];
var mapType = {};

for (var i = 0; i <= (tileNames.length - 1); i++) {
    (function(i) {
        tileOptions = {
            getTileUrl: function(coord, zoom) {
                return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
            },
            tileSize: new google.maps.Size(256, 256)
        };
        mapType[tileNames[i]] = new google.maps.ImageMapType(tileOptions);
    })(i);
};
4

3 に答える 3

4

これをうまく処理できる関数型プログラミングの概念があります

基本的に、関数には実際にはzoom変数、coordオブジェクト、tileNames[i]値の 3 つの引数がありますがtileNames[i]、コード内で一度に値を特定の値に固定し、他の 2 つの変数を実際の変数のままにしておく必要があります。

function getTileUrlBuilder(tilename) {
    return function(coord, zoom) {
        return "/maps/tiles/tile" + tilename + "/" + zoom + "_" + coord.x + "_" + coord.y;
    };
}

次に、この関数をループで使用できます。ただし、これは実際には一般的な操作であるため、bindメソッドを使用してこれを処理できます。

(function(tilename, coord, zoom) {
    return "/maps/tiles/tile" + tilename + "/" + zoom + "_" + coord.x + "_" + coord.y
}).bind(this, tileNames[i]);

thisこれにより、暗黙的なものが現在のに「バインド」されthis、最初の引数が の現在の値にバインドされますtileNames[i]

編集:これは、作業コードである必要があると思います。

var tileNames = ["beloit", "parking", "access_p"];
var mapType = {};

function getTileUrlFull(tileName, coord, zoom) {
    return "/maps2/tiles/tiles" + tileName + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png"
}

for(var i = 0; i < tileNames.length; i++) {
    mapType[tileNames[i]] = new google.maps.ImageMapType({
        getTileUrl: getTileUrlFull.bind(this, tileNames[i]),
        tileSize: new google.maps.Size(256, 256)
    });
}
于 2012-06-26T19:56:37.827 に答える
2

別の閉鎖が必要です。ループが実行された後、変数 'i' の値は 3 です。 tileNames[3] => 未定義。ただし、作成しているすべての関数には、同じ i 変数への参照が含まれています。

次のようなことを試してください:

    for (var i = 0; i < tileNames.length; i++) {
      (function(i) {
        //loop body goes here.
      })(i);
    };
于 2012-06-26T19:54:25.537 に答える
1

関数に渡す必要がありiますgetTileUrl

getTileUrl: function(i, coord, zoom) {
        return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
    },
于 2012-06-26T19:51:33.757 に答える