我是jQuery和Javascript的新手。我正在创建一个导航数据库表(NavDb)的通用对象。如果我创建1个实例,它可以完美地工作当我运行多个实例时,它失败了。我将问题追溯到我如何使用'this'。初始化/处理ajax请求的一个例程失败。表单可以包含任意数量的选择器(自动完成或下拉列表)。该例程递归地执行ajax请求,直到所有选择器都已初始化。 'this'变量在进入'success:'函数时引用ajax对象。我需要对父对象的引用,所以我在第2行创建了一个$ this。问题是它创建了一个闭包并弄乱了第二个实例(我相信这就是发生的事情)。如何获取成功函数内的父对象的引用?我可以将ajax请求绑定到父对象吗?我需要这样的东西:
var $ this = this.parent;
希望我能清楚地解释清楚。
新代码
NavDb.prototype.getSelData = function () {
if (this.curSelector >= this.selectors.length) {
return;
}
else {
var sql = this.selectors[this.curSelector].sql;
$.ajax({
url: 'php/select.php',
type: 'POST',
context: this, // Only needed 'this' not this.parentNode.
dataType: 'json',
data: {
'sql': sql
}
}).done(function (data) {
if (data.success) {
if (data.v.length > 0) {
this.selectors[this.curSelector].data = data;
if (this.selectors[this.curSelector].type == "autoComp") {
this.initAC();
};
if (this.selectors[this.curSelector].type == "dropDown") {
this.initDD();
};
}
}
this.curSelector++;
this.getSelData();
}).fail(function (XHR, textStatus, errorThrown) {
$("#status").html(getErrorText(XHR.responseText));
});
};
};
旧代码
NavDb.prototype.ajaxSelData = function () {
var $this = this;
if (this.curSelector >= this.selectors.length) {
$this = null;
return;
}
else {
var sql = $this.selectors[$this.curSelector].sql;
$.ajax({
url: 'php/select.php',
type: 'POST',
dataType: 'json',
data: {
'sql': sql
},
success: function (data) {
if (data.success) {
if (data.v.length > 0) {
$this.selectors[$this.curSelector].data = data;
if ($this.selectors[$this.curSelector].type == "autoComp") {
$this.initAC();
};
if ($this.selectors[$this.curSelector].type == "dropDown") {
$this.initDD();
};
}
} else {
alert(data.error);
}
$this.curSelector++;
$this.ajaxSelData();
}
});
};
};
答案 0 :(得分:0)
你的代码创建的闭包对每个实例都是唯一的(它为每个实例创建一个单独的闭包)所以你的理论认为闭包弄乱了第二个实例是不正确的。
所以,像你一样创建单独的变量:
var $this = this;
是一件非常好的事情,不会造成问题。
但是,如果你想要父节点,那么也许你应该这样做:
var parent = this.parent;
然后引用ajax函数中的parent
变量。
您也可以将context
参数传递给您的ajax调用,并在成功处理程序回调中根据需要设置this
参数。
$.ajax({
url: 'php/select.php',
type: 'POST',
dataType: 'json',
context: this.parent, // add this line
data: {
'sql': sql
},
success: function (data) {
// now the this pointer is set as desired in your callback here
if (data.success) {
答案 1 :(得分:0)
有关正确的上下文范围,请参阅this answer。
您可以通过多种方式确保正确的背景:
使用context
$.ajax({
url: 'php/select.php',
type: 'POST',
context: this.parentNode,
dataType: 'json',
data: {
sql: sql
},
success: function (data) {
// 'this' is parentNode
}
})
使用closure
var parentNode = this.parentNode;
success: function (data) {
//you can now use 'parentNode'
}
使用$.proxy
$.proxy(function(data){
// 'this' is parentNode
}, this.parentNode);