0

さまざまな色でレンダリングしようとしている方向のセットがあります。Google に道案内をリクエストしましたが、ルーティング結果が返されたときにそれぞれを適切な色でレンダリングできるように状態を保存する方法がわかりません。

したがって、例として、次のオブジェクトがあります。

{routes: [{start_lat : 0.0, start_lng : 0.0, end_lat : 1.0, end_lng : 1.0, color : "#ff0000"},
          {start_lat : 1.0, start_lng : 1.0, end_lat : 2.0, end_lng : 2.0, color : "#00ff00"}]}

これが私の機能です:

directionsService = new google.maps.DirectionsService();
for(var i = 0; i < routes.length; i++){
    var dir_request = {
        origin : new google.maps.LatLng(routes[i]['start_lat'], routes[i]['stop_lng']),
        destination : new google.maps.LatLng(routes[i]['end_lat'], routes[i]['end_lng']),
        travelMode : google.maps.TravelMode.WALKING
    };
    directionsService.route(dir_request, function(result, status) {
        if(status == google.maps.DirectionsStatus.OK){
            // render with custom logic depending on which route this is here
        }
    })
}

結果処理関数からアクセスできるように、状態 (たとえば、for ループのインデックス) を各要求に添付するにはどうすればよいですか?

4

3 に答える 3

1

これを行うには、クロージャー スコープ変数を使用する必要があります。ルート コールバック関数で使用しようとするとi、親関数で宣言された変数によって、内部関数からアクセスできるクロージャと呼ばれる概念が使用されます。

しかし、ループ内でクロージャーを使用すると、ループ内で作成されたすべての内部関数間でクロージャー変数の同じインスタンスが共有されるため、独自の問題があります。したがって、内部関数が呼び出されると、変数に割り当てられた最後の値が取得されますループ。

ここでの解決策は、以下に示すように、ループ内にローカル クロージャーを作成することです。

directionsService = new google.maps.DirectionsService();
for (var i = 0; i < routes.length; i++) {
    (function (idx) {
        var dir_request = {
            origin: new google.maps.LatLng(routes[idx]['start_lat'], routes[idx]['stop_lng']),
            destination: new google.maps.LatLng(routes[idx]['end_lat'], routes[idx]['end_lng']),
            travelMode: google.maps.TravelMode.WALKING
        };
        directionsService.route(dir_request, function (result, status) {
            // the variable idx will refer to the array index for the current iteration
            if (status == google.maps.DirectionsStatus.OK) {
                // render with custom logic depending on which route this is here
            }
        })
    })(i)
}
于 2013-11-05T02:47:33.293 に答える
1

いくつかの回答は、明示的なクロージャで問題を解決する方法をすでに説明しています。を使用した別の例を次に示しFunction.prototype.bindます。

directionsService.route(dir_request, (function(result, status) {
    //the this keyword now refers to the correct route object
    console.log(this);

    if(status == google.maps.DirectionsStatus.OK){
        // render with custom logic depending on which route this is here
    }
}).bind(routes[i]));

編集:

なしでそれを行う効率的な別の方法を次に示しbindます。スコープ セーフな関数をループ内にインライン化することは、反復ごとに新しい関数を作成する必要があるため、効率的ではありません。そのための関数を作成し、それを再利用することをお勧めします。

function createRouteCallback(route) {
    return function (result, status) {
        if(status == google.maps.DirectionsStatus.OK) {
            // render with custom logic depending on which route this is here

            //you can just use route here
            console.log(route);
        }
    };
}

次に、ループ内で次のことを簡単に実行できます。

directionsService.route(dir_request, createRouteCallback(routes[i]));
于 2013-11-05T03:06:52.747 に答える
0

マルカは正しい。何か奇妙なことが起こっていない限り、関数のすべての変数は callback 内で使用できますfunction(result,status)。説明といくつかの例については、こちらを参照してください。いつコールバックを作成したかはわかっているのでdir_request、コールバック コードで直接参照できます。配列iにアクセスする必要がある場合も参照できるはずです。routes

価値を伝えるのに問題がある場合は、間接的なレイヤーを追加してみてください。

function makeCallback(dir_request) {
    return function(result,status) {
        //your code, and you can refer to dir_request
    };
}

それから電話する

directionsService.route(dir_request, makeCallback(dir_request));

が作成されたときに必要な変数がロックされていることを確認するために、Greasemonkey スクリプトで一度実行する必要がありfunction()ました。

于 2013-11-05T02:47:07.500 に答える