Пожалуйста, помогите, я не мог понять это.
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'));
});
в функции выше, я знаю context: tour
устанавливает this
внутри функции this.fetchPhotos
для ссылки на Tour. Поэтому мой вопрос: почему эта часть кода tour.el.data('location')
изменяется на this.el.data('location')
?
Спасибо вам за помощь
Причина, по которой работает, заключается в том, что tour.el.data('location')
вызывается из fetchPhotos
.
Пока вы это делаете
new Tour().fetchPhotos();
и не
var f = new Tour().fetchPhotos;
f();
замена будет работать.
Но делать
this.el.on('click', 'button', this.fetchPhotos);
как последнее. Это не работает.
this.fetchPhotos
не вызывает метод, вместо этого можно представить, что это происходит так: var callback = arguments[2]; callback.call(that, args);
где that === el
.
Как charlietfl писал, это другой контекст внутри AJAX обратных вызовов, вы должны кэшировать this
для любой переменной до вызова AJAX и использовать эту переменную. Как и в переменной tour
:
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'));
});
Вне АЯКС вызова (как вяжущее событие Click), это нормально, чтобы использовать this
, но в тех функциях обратного вызова, это относится к обработчику обратного вызова
this
в$.ajax
, объявляете как другую переменную вне$.ajax