Reputation: 496
I have a view I am able to load. However the events do not fire. Here is the view:
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();
}
})
I removed one of the event functions because it wasn't important. Anyways, this view is initialized in my router:
this.mapModalView = new MapModalView();
And I have a tooltip view, which has an event inside of it, that calls the render function from ModalMapView. Here is that View:
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;
}
});
I removed the functions that I didnt think would be important again above.
Also, here is my template:
<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>
and of course, my HTML markup on the page I am working on:
<div class="modal_box"></div>
Upvotes: 2
Views: 2808
Reputation: 434975
I don't see any _this
defined anywhere so I would expect everything to stop running as soon as you call renderMap
and that would prevent your events from doing anything.
I do see this:
MapModalView = Backbone.View.extend({
//...
_this: this,
but that doesn't create a _this
in the object's scope, that just creates a default this._this
for your view instances; furthermore, when MapModalView is being built, this
will probably be window
so all you're doing is giving each MapModalView an reference to window
in this._this
.
I think all your _this
references should be this
and perhaps you want to add:
_.bindAll(this, 'renderMap, 'renderPin');
to MapModalView's initialize
method to make sure those two always have the right this
when you call them.
And now for the underlying problem now that we have mostly functional code.
Backbone views have an el
:
All views have a DOM element at all times (the el property), whether they've already been inserted into the page or not.
and they have an $el
:
A cached jQuery (or Zepto) object for the view's element.
The delegateEvents
method operators on this.$el
. You don't specify an el
(or id
, tagName
, ...) as part of your view's definition so Backbone initializes your el
to an empty <div>
and then initializes this.$el = $(this.el)
. Your constructor changes this.el
:
this.el = $('.modal_box');
but you don't do anything with this.$el
so it still refers to the empty <div>
. Remember that delegateEvents
uses this.$el
and that's not pointing at anything useful so your events don't get bound to anything in the DOM.
If you insist on setting this.el
inside your initialize
, then you'll have to set this.$el
as well:
initialize: function() {
this.el = '.modal_box';
this.$el = $(this.el);
//...
Demo: http://jsfiddle.net/ambiguous/D996h/
Or you could use setElement()
to set el
and $el
for you.
The usual approach is to set el
as part of the view's definition:
MapModalView = Backbone.View.extend({
el: '.modal_box',
//...
Demo: http://jsfiddle.net/ambiguous/NasSN/
Or you can pass the el
to the view when you instantiate it:
m = new MapModalView({el: '.modal_box'});
m.render();
Demo: http://jsfiddle.net/ambiguous/9rsdC/
Upvotes: 3
Reputation: 1127
Try this:
render: function() {
$(this.el).show().append(this.template({
model: this.model
}));
this.renderMap();
this.renderPin();
this.delegateEvents();
},
Upvotes: 1