Backbone.js eventos no disparar
-
28-10-2019 - |
Pregunta
Tengo una vista que puedo cargar. Sin embargo, los eventos no disparan. Aquí está la vista:
MapModalView = Backbone.View.extend({
events: {
'click #closeMapModal': 'closeModal',
'click #modal_streetview': 'renderStreet'
},
initialize: function(){
this.el = $('.modal_box');
this.template = _.template($('#map-modal-template').html());
_.bindAll(this, 'renderMap', 'renderPin');
},
render: function(){
$(this.el).show().append(this.template({
model: this.model
}));
this.renderMap();
this.renderPin();
},
renderMap: function(){
this.thisLat = _this.model.get('lat');
this.thisLng = _this.model.get('lng');
this.modalMap = new google.maps.Map(document.getElementById('modalMap'), {
zoom : 12,
center : new google.maps.LatLng(this.thisLat, this.thisLng), // VANCOUVER
mapTypeId : google.maps.MapTypeId.ROADMAP
});
},
renderPin: function(){
marker = new google.maps.Marker({
position : new google.maps.LatLng(this.thisLat, this.thisLng),
map : this.modalMap,
animation : google.maps.Animation.DROP,
icon : '/img/lazy-pin.png'
});
},
renderStreet: function(e){
e.preventDefault();
this.modalMap.getStreetView().setPosition(this.modalMap.center);
this.modalMap.getStreetView().setVisible(true);
},
closeModal: function(e){
alert('hello');
e.preventDefault();
$(this.el).hide().find('div').remove();
}
})
Eliminé una de las funciones del evento porque no era importante. De todos modos, esta vista se inicializa en mi enrutador:
this.mapModalView = new MapModalView();
Y tengo una vista de información sobre herramientas, que tiene un evento dentro de él, que llama a la función de renderizado desde modalMapView. Aquí está esa vista:
ToolTipView = Backbone.View.extend({
initialize: function() {
this.template = _.template($('#toolTip').html());
this.mapTemplate = _.template($('#map-modal-template').html());
this.model.bind('change:tooltip', this.toggleTooltip, this);
return this;
},
events: {
'mouseenter': 'toolTipOn',
'mouseleave': 'toolTipOff',
'click #show-restaurant-map': 'mapModal'
},
mapModal: function(){
router.mapModalView.render(this.model);
},
render: function() {
$(this.el).html(this.template({
model: this.model
}));
this.delegateEvents();
return this;
}
});
Eliminé las funciones que no pensé que serían importantes nuevamente anteriormente.
Además, aquí está mi plantilla:
<script type="text/template" id="map-modal-template">
<div id="map_modal">
<button title="Close" id="closeMapModal" class="right">Close</button>
<h3>Restaurant Map & Access Information</h3>
<ul>
<li><a href="#" title="Map View" id="modal_mapview">Map</a></li>
<li><a href="#" title="Street View" id="modal_streetview">Street View</a></li>
<li><a href="#" title="Parking & Access Info" id="modal_parking">Parking & Access Info</a></li>
</ul>
<div id="modalMap"></div>
</div>
</script>
Y, por supuesto, mi marcado HTML en la página en la que estoy trabajando:
<div class="modal_box"></div>
Solución
Prueba esto:
render: function() {
$(this.el).show().append(this.template({
model: this.model
}));
this.renderMap();
this.renderPin();
this.delegateEvents();
},
Otros consejos
No veo ninguno _this
definido en cualquier lugar para esperar que todo deje de correr tan pronto como llame renderMap
Y eso evitaría que sus eventos hagan cualquier cosa.
Veo esto:
MapModalView = Backbone.View.extend({
//...
_this: this,
Pero eso no crea un _this
En el alcance del objeto, eso solo crea un valor predeterminado this._this
para sus instancias de visión; Además, cuando se está construyendo mapmodalview, this
Probablemente será window
Entonces, todo lo que está haciendo es darle a cada mapmodalview una referencia a window
en this._this
.
Creo que todo tu _this
Las referencias deben ser this
Y tal vez quieras agregar:
_.bindAll(this, 'renderMap, 'renderPin');
a mapmodalview's initialize
método para asegurarse de que esos dos siempre tengan el derecho this
Cuando los llamas.
Y ahora para el problema subyacente ahora que tenemos en su mayoría código funcional.
Las vistas de la troncal tienen una el
:
Todas las vistas tienen un elemento DOM en todo momento (la propiedad EL), ya sea que ya se hayan insertado en la página o no.
Y tienen un $el
:
Un objeto jQuery (o zepto) almacenado en caché para el elemento de la vista.
los delegateEvents
Operadores de método en this.$el
. No especificas un el
(o id
, tagName
, ...) como parte de la definición de tu vista, así que Backbone inicializa tu el
a un vacío <div>
y luego inicializa this.$el = $(this.el)
. Tu constructor cambia this.el
:
this.el = $('.modal_box');
Pero no haces nada con this.$el
Entonces todavía se refiere al vacío <div>
. Recuérdalo delegateEvents
usos this.$el
Y eso no apunta a nada útil para que sus eventos no lleguen a nada en el DOM.
Si insiste en configurar this.el
dentro de tu initialize
, entonces tendrás que configurar this.$el
también:
initialize: function() {
this.el = '.modal_box';
this.$el = $(this.el);
//...
Manifestación: http://jsfiddle.net/ambiguueus/d996h/
O podrías usar setElement()
para establecer el
y $el
para ti.
El enfoque habitual es establecer el
Como parte de la definición de la vista:
MapModalView = Backbone.View.extend({
el: '.modal_box',
//...
Manifestación: http://jsfiddle.net/ambiguue/nassn/
O puedes pasar el el
a la vista cuando lo instancías:
m = new MapModalView({el: '.modal_box'});
m.render();
Manifestación: http://jsfiddle.net/ambiguue/9rsdc/