2015-02-23 32 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)