#javascript #google-maps #this
#javascript #google-карты #это
Вопрос:
итак, у меня есть объект, определенный следующим образом (упрощенный):
mapRoute : {
isInit : false,
latLang : "",
directionsService : null,
directionsRenderer : null,
init : function() {
if(!this.isInit) {
this.directionsService = new google.maps.DirectionsService();
this.directionsRenderer = new google.maps.DirectionsRenderer();
this.directionsRenderer.setPanel(document.getElementById("google_route_results"));
this.isInit = true;
}
},
planRoute : function() {
var from;
var to;
from = $('#addressFrom').val();
to = this.LatLang;
var directionsRequest = {
origin:from,
destination:to,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
this.directionsService.route(directionsRequest, this.planRouteCallback);
},
planRouteCallback : function(result,status){
if(status == google.maps.DirectionsStatus.OK) {
this.directionsRenderer.setDirections(result);
this.directionsRenderer.setMap(google_map_object);
} else {
this.handleErrors(status);
}
},
//handleErrors
handleErrors : function(statusCode) {
//do stuff
},
}//end mapRoute
однако, когда выполняется мой planRouteCallback, я получаю ошибки, потому что «это» относится к объекту DOMWindow, а не к моему объекту MapRoute. почему это так, и могу ли я что-нибудь с этим сделать?
Ответ №1:
Проблема в том, что функция выполняется не из контекста mapRoute
объекта. Так, например:
var foo = {bar: 10, fn: function(){ alert(this.bar); }};
foo.fn(); // called within the context of the object foo, so it alerts 10
var noContextFn = foo.fn;
noContextFn(); // uh oh, no context, alerts undefined
Когда вы передаете свой обратный вызов mapRoute.planRouteCallback
другим функциям, они теперь имеют ссылку на нужные функции, но не будут выполнять этот обратный вызов в контексте mapRoute
, как указано выше.
Вы могли бы создать анонимную функцию и использовать шаблон self = this каждый раз, когда вы передаете обратные вызовы в качестве параметров, хотя вам, вероятно, лучше исправить саму функцию раз и навсегда. Вы можете привязать функцию. После того, как mapRoute
объект был создан, вы можете запустить:
mapRoute.planRouteCallback = mapRoute.planRouteCallback.bind(mapRoute);
(Обратите внимание, bind()
может быть реализовано не во всех браузерах, смотрите MDC для реализации, которую вы можете использовать).
Ответ №2:
Во-первых, «this» в javascript немного сложно и зависит от того, где была вызвана функция, а не только от того, где она была определена.
Самое быстрое кроссбраузерное решение — использовать замыкание. У Google на самом деле есть отличная статья о закрытии с помощью Google Maps здесь.
http://code.google.com/intl/en/apis/maps/documentation/javascript/v2/events.html#Event_Closures
У вас есть доступ к методу GEvent.bind, который вы могли бы использовать для правильной ссылки на свой обратный вызов.
GEvent.bind(map, "click", myCounter, myCounter.increment);
Но я не знаю, как реализовать это с помощью direction route. Кроме того, это может быть устаревшим с версией v2. Вот лучшая ссылка на maps v3
http://code.google.com/intl/en/apis/maps/documentation/javascript/events.html
Итак, возможно, рассмотрим что-то вроде этого:
var directionsRequest = {
origin:from,
destination:to,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
var that = this;
var planRouteCallback = function(result,status){
if(status == google.maps.DirectionsStatus.OK) {
that.directionsRenderer.setDirections(result);
that.directionsRenderer.setMap(google_map_object);
} else {
that.handleErrors(status);
}
},
this.directionsService.route(directionsRequest, planRouteCallback);
Простые замыкания действительно помогают с обратными вызовами.
Ответ №3:
В итоге я использовал прокси-сервер jQuery для получения желаемых результатов
this.directionsService.route(directionsRequest, $.proxy( this.planRouteCallback,this));