传递给KO点击绑定的Typescript成员方法以“错误”范围结束

时间:2012-11-05 17:43:27

标签: knockout.js typescript

我正在使用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。单击此按钮时,函数的“email”参数是MainViewModel中正确选择的电子邮件,但函数的范围也是EmailViewModel,而不是定义函数的MainViewModel。

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

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

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

4 个答案:

答案 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');