Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Knockout.js 传递到KO click绑定中的Typescript成员方法以“";“错误”;范围_Knockout.js_Typescript - Fatal编程技术网

Knockout.js 传递到KO click绑定中的Typescript成员方法以“";“错误”;范围

Knockout.js 传递到KO click绑定中的Typescript成员方法以“";“错误”;范围,knockout.js,typescript,Knockout.js,Typescript,我正在使用KnockoutJS和Typescript编写一个单页应用程序 问题在于,我有一个MainViewModel,其方法如下: public addToCase(email) { this.addToCaseVM.setEmail(email, this.getEmailBody()); }; 我的页面中有一个电子邮件视图,其中有一个“添加到案例”按钮,该按钮以html格式绑定,如下所示: <a class="btn btn-info" data-bind="click:

我正在使用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>

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

class MainViewModel {

    static self:MainViewModel;

    constructor() {
        self = this;
    } 

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

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

data-bind="click: function(data) {$root.addToCase(data,$root)}"
您可以使用
()=>
来保留词法范围

为了演示的目的,我将其制作成了一个完整的工作示例,但是您可以看到,正是
()=>
发挥了神奇的作用

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

我的解决方案是声明类方法并将其保留为空,直到调用构造函数,然后定义方法体。这样,方法的作用域就会正确

class MainViewModel {

    addToCase: (email) => void;

    constructor() {
        this.addToCase = (email) => {
            this.addToCaseVM.setEmail(email, this.getEmailBody());
        };
    }
}

在我的例子中,这实际上不起作用,因为MainViewModel类的addToCase成员作为函数闭包被传递给Knockout,然后由具有不同作用域的jQuery调用。问题是,typescript编译器在您的示例中为您生成的_this变量在我的应用程序中首先生成的作用域错误。这是可行的,但我希望有一个更干净的实现,或者在MainViewModel是任何通用父视图模型而不是单例的其他情况下也可以使用。同意,单身汉有点做作,@MattBurland的答案是更好的。这是一个解决办法,但经过一些测试后,我觉得这是对的。在将成员函数调用包装在外部闭包中之后,它允许内部调用具有正确的范围,并显式地说明您正在尝试执行的操作。我将在我的项目中使用这个。谢谢,这是个好办法。工作得很有魅力!
class MainViewModel {

    addToCase: (email) => void;

    constructor() {
        this.addToCase = (email) => {
            this.addToCaseVM.setEmail(email, this.getEmailBody());
        };
    }
}