【发布时间】:2013-04-11 00:58:44
【问题描述】:
所以我尝试在网络应用程序上使用 $.Deferred 对象来确保在尝试执行 [目标] 之前已完成 [先决条件]。
长话短说,我想使用的真实代码看起来像......
function QuoteReview(openQuote) {
//constants
this.RETIRE_AFTER=180; //...seconds. Do not use cached values older than this, instead, reload them
this.lastLoadedQuotes=undefined;
this.quotes=[];
this.currentQuote={
chosen:false,
id:undefined,
loaded:false,
name:undefined,
pricebook:undefined,
prontoId:undefined,
state:undefined,
reviewer:undefined,
opportunityId:undefined,
accountCode:undefined,
items:[],
lastLoad:undefined
};
var _curQuote=this.currentQuote;
this.displayQuote=function(forceLoad) {
//if forceLoad was specified as true, the quote has never been loaded, or the last load is past it's retirement age, load it first
if (forceLoad || typeof this.currentQuote.lastLoad == "undefined" || ((new Date() - this.currentQuote.lastLoad)/1000)>this.RETIRE_AFTER)
this.loadQuote().then(this._displayQuote);
else
this.displayQuote();
}
this._displayQuote=function() {
console.log(this); //Displays the deferred object
console.log(self); //reference error (expected)
console.log(currentQuote); //reference error
console.log(_curQuote); //reference error
}
this.loadQuote=function() {
if (this.currentQuote.chosen) {
var self=this;
return $.getJSON("queries/getQuote.php?id="+encodeURIComponent(this.currentQuote.id),function(data) {
//TODO add in the error/logged out handling
data=data.data[0];
self.currentQuote.name=data.name;
self.currentQuote.pricebook=data.pricebook;
self.currentQuote.prontoId=data.prontoId;
self.currentQuote.state=data.state;
self.currentQuote.reviewer=data.reviewer;
self.currentQuote.opportunityId=data.opportunityId;
self.currentQuote.accountCode=data.accountCode;
self.currentQuote.items=data.items;
self.currentQuote.lastLoad=new Date();
self.currentQuote.loaded=true;
});
} else {
console.log("tried to load quote before it was chosen!");
return $.Deferred();
}
}
}
但我已经编写了一些测试代码来更容易地显示问题:
function getSomeAjax() {
return $.getJSON("queries/quoteSearch.php?needle=",function(data) {
console.log("got the response");
console.log(data);
window.someInfo=data;
});
}
function _useIt() {
console.log("we would use the data here, doing some dom type stuff");
console.log(window.someInfo);
console.log(this);
}
function useIt() {
getSomeAjax().then(_useIt);
}
(该查询只返回一些数据......在这种情况下并不重要,我们不做任何事情)
问题是,当我在_useIt() 函数中记录this 时,我看到了延迟对象的范围。现在这完全有道理,我当时正在打电话 - 延迟对象的成员,但有人知道解决这个问题的方法吗?如果我使用.apply(window,[]),它似乎甚至不会调用_useIt。现在,看到我只是在页面上使用quoteReview = new QuoteReview();,并且我将始终只有一个 QuoteReview 对象,我知道我可以只使用quoteReview.currentQuote 而不是this.currentQuote,如果推我不介意这样做来推,但我也想知道这样做的正确方法。
回答后编辑:
在这种情况下,我最终使用了 Travis 和 Esthete 的答案组合。我发现 Aesthete 在回调函数中为我工作,但后来我意识到我还需要创建一个 _curParts、_curQuotes 和 _curPart 变量;我还使用在loadQuote() 中分配的var self=this 来访问匿名ajax 函数中的成员,但这似乎是双重工作(考虑到self 也具有_curQuote 的所有属性)。相反,我在整个构造函数的范围内使用了var self=this,并使用它来访问匿名ajax 函数和作为回调传递给.then() 的函数中的成员。
【问题讨论】:
标签: javascript jquery closures jquery-deferred