我正在使用KnockoutJS和Typescript编写单页应用程序。
问题是这个,我有一个MainViewModel,方法是:
public addToCase(email) {
this.addToCaseVM.setEmail(email, this.getEmailBody());
};
我的页面中有一个电子邮件视图,其中包含一个“添加到案例”按钮,该按钮绑定在html中,如下所示:
<a class="btn btn-info" data-bind="click: $root.addToCase" data-toggle="modal" href="#addToCaseModal"><i class="icon-plus-sign"></i> Add To Existing Case</a>
$ root是我的MainViewModel。单击此按钮时,函数的“email”参数是MainViewModel中正确选择的电子邮件,但函数的范围也是EmailViewModel,而不是定义函数的MainViewModel。
我理解为什么会发生这种情况,我对如何解决Typescript中的特定问题感兴趣,因为我无法像在纯javascript中那样声明指向MainViewModel实例的指针:
var MainViewModel = (function(){
var self = this;
this.addToCase = function(email) {
self.addToCaseVM.setEmail(email, self.getEmailBody());
};
})();
答案 0 :(得分:7)
我的解决方案是声明类方法并将其保留为空,直到调用构造函数,然后定义方法体。这种方法的方法将是正确的。
class MainViewModel {
addToCase: (email) => void;
constructor() {
this.addToCase = (email) => {
this.addToCaseVM.setEmail(email, this.getEmailBody());
};
}
}
答案 1 :(得分:2)
如果您的MainViewModel
是单身,那么您可以使用该模式创建静态参考。
class MainViewModel {
static self:MainViewModel;
constructor() {
self = this;
}
addToCase = function(email) {
MainViewModel.self.addToCaseVM.setEmail(email, MainViewModel.self.getEmailBody());
}
}
答案 2 :(得分:2)
您可以使用函数文字,以便可以将父对象传递给addToCase函数,但这似乎可以解决问题而不是解决问题。
data-bind="click: function(data) {$root.addToCase(data,$root)}"
答案 3 :(得分:0)
您可以使用() =>
来保留词汇范围。
我已经将它变成了一个完整的示例,用于演示目的,但你可以看到只有() =>
才能发挥魔力。
function setEmail(email: string, callback: Function) {
callback();
}
class MainViewModel {
addToCase(email: string) {
setEmail(email, () => {this.getEmailBody();});
}
getEmailBody() {
alert('getEmailBody');
}
}
var model = new MainViewModel();
model.addToCase('hello');