6

我正在使用 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>&nbsp;Add To Existing Case</a>

$root 是我的 MainViewModel。单击此按钮时,函数的“电子邮件”参数是 MainViewModel 中正确选择的电子邮件,但函数的范围也是 EmailViewModel,而不是定义函数的 MainViewModel。

我理解为什么会发生这种情况,我对如何解决 Typescript 中的特定问题很感兴趣,因为我无法像在纯 JavaScript 中那样声明指向 MainViewModel 实例的指针:

var MainViewModel = (function(){ 
    var self = this; 

    this.addToCase = function(email) {
        self.addToCaseVM.setEmail(email, self.getEmailBody());
    };
})();
4

4 回答 4

7

我对此的解决方案是声明类方法并将其留空,直到调用构造函数,然后定义方法体。这样方法的范围将正确。

class MainViewModel {

    addToCase: (email) => void;

    constructor() {
        this.addToCase = (email) => {
            this.addToCaseVM.setEmail(email, this.getEmailBody());
        };
    }
}
于 2012-11-06T10:08:31.473 回答
2

如果您MainViewModel是单例,那么您可以使用该模式来创建静态引用。

class MainViewModel {

    static self:MainViewModel;

    constructor() {
        self = this;
    } 

    addToCase = function(email) {
        MainViewModel.self.addToCaseVM.setEmail(email, MainViewModel.self.getEmailBody());
    }
}
于 2012-11-05T18:05:16.323 回答
2

您可以使用函数文字,以便将父对象传递给 addToCase 函数,但这似乎是在解决问题而不是解决问题。

data-bind="click: function(data) {$root.addToCase(data,$root)}"
于 2012-11-05T18:38:17.570 回答
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');
于 2012-11-05T18:59:17.867 回答