我有一个mvc应用程序,我在TypeScript中编写客户端代码,以及使用几个众所周知的javascript库,包括knockout,amplifyjs和requirejs。我遇到了预期行为不会发生的情况。
export class OrganizationOverviewViewModel{
openedAssessments = ko.observableArray();
availableSurveys = ko.observableArray();
organizationAgentId = ko.observable();
organizationName = ko.observable();
selectedSurvey = ko.observable();
public addSurvey() {
if (this.selectedSurvey() === undefined) {
mh.MessageHub.showError("Please Select a Survey", "what");
}
else {
// we can do the post.
// get the selected survey
var surveyId = this.selectedSurvey();
// call the server to add the survey
amplify.request("addSurveyToOrganization", {
"surveyId": surveyId,
"organizationAgentId": this.organizationAgentId()
},
function (data) {
var context = ko.contextFor($('#mainContent')[0]).$data;
context.openedAssessments.push({ surveyId: data.SurveyId, SurveyName: data.SurveyName, NumberOfResponses: data.ResponseCount });
context.availableSurveys.remove(function (item) { return item.SurveyId == surveyId; });
});
}
}
}
问题出在addSurvey()中。在放大请求中,我希望'this'关键字仍然指向类的实例。相反,它指向整个窗口。我有一个解决方法,就是使用knockout来从DOM中获取上下文,但这看起来似乎不是一个好主意。
使用打字稿有更好的方法吗?
答案 0 :(得分:5)
在Typescript中,“this”关键字遵循javascript语义而不是C#等OO语言的语义(现在?)
“this”正确指向对象的唯一位置是通过构造函数。所以你需要写这样的东西:
export class OrganizationOverviewViewModel{
public addSurvey;
constructor() {
this.addSurvey = () => {
// you can safely use 'this' in here
...
}
}
:
}
编辑:新版本(0.9.1)允许您对lambda字段初始值设定项使用“this”( NOT函数)。因此,您可以使用以下内容转换为上面的代码。
export class OrganizationOverviewViewModel{
public addSurvey = () => {
// you can safely use 'this' in a field initializer
}
public badSurvey_dont_use_this() {
// 'this' is probably not the 'this' you're looking for
}
}
答案 1 :(得分:0)
看看TypeScript and Knockout binding to 'this' issue - lambda function needed? - 这与Ray提到的看似正确的方法相同