7

Google Maps v3 용으로 만든 모듈을 가지고 있는데, Backbone.js보기 생성자로 변환하려고합니다.Google지도가 포함 된 Backbone.js -이 사용자와 리스너의 문제

여기에 지금까지 내보기 모듈의 :

pg.views.CreateMap = Backbone.View.extend({ 

    tagName: "div", 
    className: "map", 

    events: {}, 

    latitude: "-23.56432", 
    longitude: "-46.65183", 

    initialize: function() { 
    _.bindAll(this, 'render', 'dragMarker', 'dragMap'); 

    this.latlng = new google.maps.LatLng(this.latitude, this.longitude); 
    var myOptions = { 
     zoom: 16, 
     center: this.latlng, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    this.map = new google.maps.Map($(this.el)[0], myOptions); 
    this.marker = new google.maps.Marker({ 
     map: this.map, 
     position: this.latlng, 
     draggable: true 
    }); 

    google.maps.event.addListener(this.marker, "dragend", this.dragMarker()); 

    google.maps.event.addListener(this.map, "dragend", this.dragMap()); 

    }, 

    render: function() { 
    return this; 
    }, 

    dragMarker: function() { 
    this.latlng = this.marker.getPosition(); 
    this.map.panTo(this.latlng); 
    }, 

    dragMap: function() { 
    this.latlng = this.map.getCenter(); 
    this.marker.setPosition(this.latlng); 
    } 

}); 

난 데 문제는 구글 맵 이벤트 리스너이며 어떻게 "이"내가 코드 뒤에 데 문제를 설명 할 것이다 처리됩니다.

내가 원래 dragMarker 및 dragMap 방법 대신 초기화 블록이 두 가지를 가지고 있지 않았다 것을

google.maps.event.addListener(this.marker, "dragend", function() { 
    this.latlng = this.marker.getPosition(); 
    this.map.panTo(this.latlng); 
}); 

google.maps.event.addListener(this.map, "dragend", function() { 
    this.latlng = this.map.getCenter(); 
    this.marker.setPosition(this.latlng); 
}); 

나는이 첫 번째 방법으로 발생하는 문제입니다 "이"언급 된 익명 함수 내부 "this.marker"및 "this.map"각각. 이 첫 번째 접근법의 문제점은 첫 번째 리스너에서 "this.map"을 참조 할 방법이 없으므로 panTo()를 수행 할 수 없다는 것입니다. 두 번째 리스너를 사용하면 "this.marker"를 참조 할 방법이 없으므로 setPosition()을 사용하여 해당 마커 주변의지도를 다시 검색 할 수 없습니다.

나는 리스너에서 익명의 함수를 꺼내서 뷰의 메서드로 선언 할 수 있다고 생각했다. 뷰의 메서드로 선언하면 _.bindAll (this, "dragMarker", "dragMap");

이 접근 방식의 문제는 다음과 같이 이벤트 블록에 청취자를 작성했다 있다는 것입니다 :

google.maps.event.addListener(this.marker, "dragend", this.dragMarker()); 

google.maps.event.addListener(this.map, "dragend", this.dragMap()); 

이 내가 newmap = 새로운 pg.views.CreateMap와 생성자 호출 될 때 의미; "this.dragMarker()"및 "this.dragMap()"이 "끌기"이벤트가 트리거 될 때 콜백으로 평가되는 대신 즉시 평가 된 것입니다.

google.maps.event.addListener(this.marker, "dragend", function() { 
    this.dragMarker(); 
}); 

google.maps.event.addListener(this.map, "dragend", function() { 
    this.dragMap(); 
}); 

불행하게도 이것은 또한 다시 이전 문제에 대한이 "이" "this.dragMarker"더 이상이 참조하는 저를 제공합니다 :

그때 생각 문제 없음과 같이 익명 함수에서 그 업 포장하지 내가 만든 부모 개체에, 대신 "this.marker"를 다시 참조하십시오. 두 번째 리스너에서도 같은 문제가 발생합니다.

저는 완전히 여기에서 붙어 있습니다. 누구든지이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

+0

이벤트 처리기를 연결하는 올바른 방법은 'google.maps.event.addListener (this.marker, "dragend", this.dragMarker); (괄호없이)와 같습니다. 하지만 이것은 컨텍스트 문제를 해결하지 못합니다. –

답변

6

dragend에 대한 익명 함수를 가져 와서 명시 적으로 바인딩하십시오.

_.bindAll(this, 'dragMarker', 'dragMap'); 
google.maps.event.addListener(this.marker, "dragend", this.dragMarker); 
/* etc ... */ 

이 방법 this는 항상 CreateMap 경우에도 문맥라고하는 연결됩니다.

+0

in dragMarker : function() {}, 어떻게 google.maps.event에서 가져올 수 있습니까? – nXqd

5

Javascript에서 해당/자체 해킹 공통을 사용하여이 문제를 해결했습니다.

var self = this; 

google.maps.event.addListener(this.marker, "dragend", function() { 
    self.latlng = this.getPosition(); 
    self.map.panTo(self.latlng); 
}); 

google.maps.event.addListener(this.map, "dragend", function() { 
    self.latlng = this.getCenter(); 
    self.marker.setPosition(self.latlng); 
}); 

누구나이 해킹이 필요하지 않은 해결책이 있다면, 나는 모두 귀입니다.

+0

그건 실제로 해킹이 아니에요. 내가 한 것입니다. –

+0

해킹이 아닙니다. Dougl Crockford는 var = this에 대해 이야기합니다. 그의 유이 비디오. – jspooner

+0

요즘에는 _.bind() 접근 방식을 사용합니다. 나는 그것이 훨씬 더 깨끗하고 엉망이 될 가능성이 적다는 것을 발견했다. (예 : var 앞에 놓는 것을 잊어 버리는 것; 예 :) –

관련 문제