Reputation: 349
Please help, I couldn't figure this out.
function Tour(el) {
var tour = this;
this.el = el;
this.fetchPhotos = function() {
$.ajax('/photos.html', {
data: {location: tour.el.data('location')},
context: tour,
success: function(response) {
this.el.find('.photos').html(response).fadeIn();
},
error: function() {
this.el.find('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
},
timeout: 3000,
beforeSend: function() {
this.el.addClass('is-fetching');
},
complete: function() {
this.el.removeClass('is-fetching');
}
});
}
this.el.on('click', 'button', this.fetchPhotos);
}
$(document).ready(function() {
var paris = new Tour($('#paris'));
});
in the function above, I know the context: tour
sets this
inside the this.fetchPhotos
function to reference Tour. So my question is why can this part of code tour.el.data('location')
change to this.el.data('location')
?
Thank you in advanced for your help
Upvotes: 0
Views: 85
Reputation: 2927
As charlietfl wrote, this is a different context inside ajax callbacks, you have to cache this
to any variable before ajax call and use that variable. Like you did in tour
variable:
function Tour(el) {
var tour = this;
this.el = el;
this.fetchPhotos = function() {
$.ajax('/photos.html', {
data: {location: tour.el.data('location')},
context: tour,
success: function(response) {
tour.el.find('.photos').html(response).fadeIn();
},
error: function() {
tour.el.find('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
},
timeout: 3000,
beforeSend: function() {
tour.el.addClass('is-fetching');
},
complete: function() {
tour.el.removeClass('is-fetching');
}
});
}
this.el.on('click', 'button', this.fetchPhotos);
}
$(document).ready(function() {
var paris = new Tour($('#paris'));
});
Outside of the ajax call (like the click event binder) it is ok to use this
, but in those callback functions, it refers to that callback handler
Upvotes: 0
Reputation: 83273
The reason that works is because tour.el.data('location')
is called from fetchPhotos
.
As long as you do
new Tour().fetchPhotos();
and not
var f = new Tour().fetchPhotos;
f();
the replacement will work.
But doing
this.el.on('click', 'button', this.fetchPhotos);
is like the latter. It does not work the same.
Upvotes: 3