因此,我尝试在 Web 应用程序上使用 $.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);
}
(该查询只返回一些数据......在这种情况下并不重要,我们不做任何事情)
问题是,当我登录this
该_useIt()
函数时,我看到了延迟对象的范围。现在这是完全有道理的,我当时正在调用 - 延迟对象的成员,但是有人知道解决这个问题的方法吗?如果我使用.apply(window,[])
它似乎甚至不会调用 _useIt。现在,看到我只是quoteReview = new QuoteReview();
在页面上使用并且我将始终只有一个 QuoteReview 对象,我知道我可以做quoteReview.currentQuote
而不是this.currentQuote
,如果推来推去我不介意这样做,但我也会想知道这样做的正确方法。
回答后编辑:在这种情况下,我最终使用了 Travis 和 Esthete 的答案组合。我发现 Aesthete 在回调函数中为我工作,但后来我意识到我还需要创建一个_curParts
,_curQuotes
和_curPart
变量;我也使用了一个var self=this
assigned insideloadQuote()
来访问匿名ajax函数中的成员,但这似乎是双重工作(考虑到self
还具有的所有属性_curQuote
)。相反,我var self=this
在整个构造函数的范围内使用它来访问匿名 ajax 函数和.then()
作为回调传递的函数中的成员。