我正在处理一个关于Object内部的Ajax回调的问题。 请考虑以下代码:
Search.prototype =
{
ask : function( query )
{
// Display loader
$('.loader').show();
$.ajax({
dataType : 'jsonp',
type : 'GET',
url : 'http://api.deezer.com/search/track/',
data : {
output : 'jsonp',
q : query
}
}).done(function(res) {
this.loadResults( res );
// [Error] Object success has no method 'loadResult'
});
},
loadResults : function (res)
{
// Hide loader
$('.loader').hide();
console.log( res );
// doing some stuff
// ...
}
}
var search = new Search();
search.ask( 'eminem' );
我收到错误Object success has no method loadResult
,这是有意义的,因为回调是匿名jQuery函数的一部分。
但是如何获取我的初始对象实例?
我一直在尝试使用var = this;在Ajax调用之前,但由于同样的原因,我不会工作。
我不知道是否可以这样做,或者问题来自我的代码全球组织。随意告诉我最佳实践:)
先谢谢。
我在代码中混淆了一些东西,虽然我没有必要在这里发帖,但我终于在我的代码中发现了问题。 对不起。
这是我的完整代码,现在正在运行:
define(['jquery'], function($) {
var Search = function()
{
this._keyDownTimer = 0;
this._searchDelay = 1000; // ms
};
Search.prototype =
{
// The init function that I though it was unnecessary to post here. Sorry :/
init : function()
{
$('#q').on('keydown', (function(evt) {
clearTimeout( this._keyDownTimer );
this._keyDownTimer = setTimeout( (function() {
this.ask( $('#q').val() );
}).bind( this ), this._searchDelay); /* <-- Here's the solution.
I forgot to bind `this`
to the timeout callback function,
so the `this` under all of my code
was referring to the anonymous function
of this callback. */
}).bind( this ));
},
ask : function( query )
{
// Display loader
$('.loader').show();
console.log(this); // Now `this` refers to my object :)
var req = $.ajax({
dataType : 'jsonp',
type : 'GET',
url : 'http://api.deezer.com/search/track/',
context : this,
data : {
output : 'jsonp',
q : query
}
});
req.done(function(res) {
this.loadResults(res);
});
},
loadResults : function (res)
{
// Hide loader
$('.loader').hide();
// doing some stuff
// ...
}
};
return new Search;
});
感谢您的回复,这确实有所帮助。
Pb解决了。
答案 0 :(得分:25)
有几种方法可以做到这一点。
您可以为ajax选项设置context
设置:
jQuery.ajax
context
设置$.ajax({
context: this
Function.prototype.bind
.done(function (res) {
}.bind(this));
然而,这并不像......那样受到广泛支持。
jQuery.proxy
为此目的而创建。
.done($.proxy(function (res) {
}, this);
var self = this;
$.ajax({
/* snip */
.done(function (res) {
self.loadResults(res);
这通常在JavaScript中完成,以便在较低范围内访问this
。
$.ajax({
/* snip */
.then(res => this.loadResults(res));
答案 1 :(得分:6)
您可以在此处使用$.ajax() context
对象,如:
$.ajax({
url : 'http://api.deezer.com/search/track/',
context: this,
...
}).done(function (res) {
this.loadResults( res );
});
答案 2 :(得分:3)
您可以使用ES5 .bind
功能正确设置this
:
$.ajax(...).done(this.loadResults.bind(this));
(使用上面链接中的填充程序,或旧浏览器上的jQuery $.proxy
等效项。)
或者,将context: this
添加到$.ajax
选项:
$.ajax({
...,
context: this
}).done(this.loadResults);
请注意,在任何一种情况下,您都将覆盖jQuery在this
中传递ajax选项对象的默认行为。
P.S。 return
$.ajax()
链的结果也是一种很好的做法,这样对象的用户就可以将额外的回调(例如.fail
处理程序)链接到它。