如何使用typescript和knockout调用对象实例方法

时间:2013-09-23 18:31:07

标签: knockout.js typescript

我正在尝试使用Typescript和knockout做一些简单的事情,但无法让它工作。随着我的typescipt代码库的增长,似乎我的视图模型正在增长,需要在主类和子类中进行很好的建模。打字稿非常适合它!结合淘汰赛我遇到了烦人的问题/错误/情况......任何帮助表示赞赏!!!这是一些打字稿代码:

class subClassA {
  counter  =0;
  incCounter(){
    this.counter++;
    console.log("counter incs: "+this.counter);
  }
}

class MainViewModel {
  a = new subClassA();


  constructor(){
    this.a.incCounter(); // this works...
  }
  incCounterIndirect(){
    this.a.incCounter(); // this works....
  }
}
ko.applyBindings(new MainViewModel() );

HTML:

<a data-bind="click: $root.incCounterIndirect ">Indirect does work</a>
<a data-bind="click: $root.a.incCounter ">Direct does NOT work</a>

显然我需要'直接'路由才能工作,即直接从data-bind调用subClasses上的方法。否则,我需要在mainviewmodel上为每个子类/成员创建代理成员......

哪个绑定前缀或其他任何技巧都可以从点击处理程序调用对象A的成员。

任何帮助表示赞赏, 保罗

3 个答案:

答案 0 :(得分:5)

使用带有胖箭头的实例成员(在TS 0.9.x中引入)来克服原型成员的this范围问题:

class subClassA {
  counter=0;
  incCounter= ()=>{  // Notice difference
    this.counter++;
    console.log("counter incs: "+this.counter);
  }
}

class MainViewModel {
  a = new subClassA();


  constructor(){
    this.a.incCounter(); 
  }
  incCounterIndirect= ()=>{    // Notice difference
    this.a.incCounter(); 
  }
}
ko.applyBindings(new MainViewModel() );

答案 1 :(得分:2)

我不熟悉打字稿,但我认为答案应与此类似:

class subClassA {
  counter  =0;
  self = this;
  incCounter(){
    self.counter++;
    console.log("counter incs: "+self.counter);
  }
}

问题在于“this”关键字。它在您的两个不同版本中获得不同的值。为了确保它始终具有相同的值,您可以在自变量中捕获此关键字的值并使用它。

以下是javascript版本的小提琴:http://jsfiddle.net/nilgundag/ySmw3/

function subClassA() {
    this.counter  = 0;
    var self = this;
    this.incCounter = function(){
        self.counter++;
        console.log("counter incs: "+self.counter);
    }
}

function MainViewModel() {
    this.a = new subClassA();
    this.incCounterIndirect=function(){
        this.a.incCounter(); // this works....
    };
}
ko.applyBindings(new MainViewModel() );

答案 2 :(得分:1)

不是改变处理程序以使用胖箭头,而是改变你的绑定方式:

<a data-bind="click: $root.a.incCounterIndirect.bind($root.a)">This will work</a>

这将创建一个新函数,其“this”参数是视图模型,这使得该方法的行为类似于实例方法。

在这里工作JSFiddle:http://jsfiddle.net/Vjknn/