2015-02-23 77 views
3

从Typescript和KnockoutJS一起开始,我遇到了一个我现在还无法解释的错误。 HTML如下所示:Typescript KnockoutJS点击绑定错误

<div class="panel panel-body"> 
    <div class="list-group" data-bind="foreach: Items()"> 
     <a href="#" class="list-group-item" 
      data-bind="text:Name, click: $parent.SetCurrent"> 
     </a> 
    </div> 
</div> 

打字稿如下:

/// <reference path="knockout.d.ts"/> 
/// <reference path="jquery.d.ts" /> 

module ViewModels { 
    export class ItemViewModel { 
     public Name: KnockoutObservable<string>; 

     constructor(name: string) { 
      this.Name = ko.observable(name); 
     }//constructor 
    } 

    export class MainViewModel { 
     public SelectedItem: KnockoutObservable<ItemViewModel>; 
     public Items: KnockoutComputed<Array<ItemViewModel>>; 

     constructor() { 
      this.SelectedItem = ko.observable<ItemViewModel>(); 
      this.Items = ko.computed({ 
       owner: this, 
       read:() => { 
        return this.get_items(); 
       } 
      }); 
     } 

     //TODO: replace this with knockout.mapping plugin transforms 
     private convert_from_model(items_model) { 
      var arr = new Array<ItemViewModel>(); 
      var owner = this; 
      items_model.forEach(function (item) { 
       var d = new ItemViewModel(item.name); 
       arr.push(d); 
      }); 
      return arr; 
     } 

     private get_items(): Array<ItemViewModel> { 
      var items = [{ "name": "AAAA" }, { "name": "BBBB" }, { "name": "CCCC" }, { "name": "DDDD" }]; 

      var items_c = this.convert_from_model(items); 
      return items_c; 
     } 

     public SetCurrent(item: ItemViewModel) { 
      this.SelectedItem(item); 
     } 
    } 
} 

window.onload =() => { 
    ko.applyBindings(new ViewModels.MainViewModel()); 
}; 

问题是设置上单击事件当前项目。

public SetCurrent(item: ItemViewModel) { 
    this.SelectedItem(item); 
} 

单击事件正确调用的setCurrent,但 '这' 是型ItemViewModel没有MainViewModel理所应当的。我错过了明显的东西吗?

这里是一个VS2013 solution与一切repro问题。

感谢

+1

有所帮助: https://www.youtube.com/watch?v=tvocUcbCupA – basarat 2015-02-23 22:24:10

回答

6
click: $parent.SetCurrent 

淘汰赛总是调用事件处理程序与this集到当前视图模型。这种特定的结合方式(对敲除)“调用$parent.SetCurrent当前视图模型作为this”。

最简单的解决方法是使用一个箭头功能总是有正确的this

// Change the definition of SetCurrent like so: 
    public SetCurrent = (item: ItemViewModel) => { 
     this.SelectedItem(item); 
    } 
+0

这一个应该做的伎俩 – 2016-11-15 06:43:32

3

事实证明,这是一个共同的结合错误。 的解决办法是强制约束力与

<a href="#" class="list-group-item" 
      data-bind="text:Name, click: $parent.SetCurrent.bind($parent)"> 
</a> 
1

您需要可以捕捉this在封闭了的setCurrent或绑定$parent.SetCurrent$parent。对于前者,打字稿提供了一个很好的方式,用lambda表达式来做到这一点,但要注意的setCurrent将不再对MainViewModel的原型定义:

SetCurrent = (item: ItemViewModel) => { 
    this.SelectedItem(item); 
} 

对于后者,改变点击结合$parent.SetCurrent.bind($parent)