在Ajax回调中访问`this`,都在Object内
我正在处理一个关于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解决了。
有几种方法可以做到这一点。
您可以为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
。
箭头具有词法绑定function
$.ajax({ /* snip */ .then(res => this.loadResults(res));
你可以在这里使用$ .ajax() context
对象,如:
$.ajax({ url : 'http://api.deezer.com/search/track/', context: this, ... }).done(function (res) { this.loadResults( res ); });
您可以使用ES5 .bind
函数正确设置:
$.ajax(...).done(this.loadResults.bind(this));
(使用上面链接中的垫片,或旧浏览器上的jQuery $.proxy
等效项)。
或者,将context: this
添加到$.ajax
选项:
$.ajax({ ..., context: this }).done(this.loadResults);
请注意,在任何一种情况下,您都将覆盖jQuery在此中传递ajax选项对象的默认行为。
ps return
$.ajax()
链的结果也是一种好习惯,这样对象的用户就可以将额外的回调(例如.fail
处理程序)链接到它。