2012-10-07 16 views
7

コード:活字体間違ったコンテキストこの

export class ViewModel { 
     public users: knockout.koObservableArrayBase; 

     constructor() { 
      this.users = ko.observableArray([]); 
      this.removeUser = this.removeUser.bind(this);//<-- Here compiller shows error 
     } 

     removeUser(user: User): void { 
      this.users.remove(user); 
     } 
} 

HTML:

<table> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Surname</th> 
     </tr> 
    </thead> 
    <tbody data-bind="foreach: users"> 
     <tr> 
      <td><a href="#" data-bind="click: $root.removeUser">Remove</a></td> 
      <td data-bind="text: name"></td> 
      <td data-bind="text: surname"></td> 
     </tr> 
    </tbody> 
</table> 

問題ははremoveUser方法です。デフォルトでは、コンテキストをバインドしないと、this == UserToDelete - viewModelオブジェクトではありません。コンストラクタに追加した場合:this.removeUser = this.removeUser.bind(this); (manually enforce context)、context == viewmodelですが、「関数を(user:User)=> voidにするとコールシグネチャは必要ですが、Functionには関数がありません」という文言があります。

+0

あなたが混乱したHTMLを気にしない場合、これは別の方法です:Remove

答えて

5

私はkoに慣れていないので、おそらくコンテキスト切り替えを解決する良い方法がありますが、あなたのtypescriptコンパイラエラーは 'bind'が 'removeUser'の型と互換性のない 'Function' 。次のようにあなたは、元の型シグネチャに戻す機能をキャストすることによってこの問題を解決することができるはずです。

this.removeUser = <(user: User) => void> this.removeUser.bind(this); 
2

まあ私は私の問題を解決するために、以下の基本クラスを思い付いた理由も同じ問題がthatsの持っていた

export class ViewModelBase { 
    private prefix: string = 'On'; 

    public Initialize() { 
     for (var methodName in this) { 
      var fn = this[methodName]; 
      var newMethodName = methodName.substr(this.prefix.length); 
      if (typeof fn === 'function' && methodName.indexOf(this.prefix) == 0 && this[newMethodName] == undefined) { 
       this[newMethodName] = $.proxy(fn, this); 
      } 
     } 
    } 
} 

あなたのクラスのすべてのメンバをループし、メソッドがOnで始まる場合、それは正しいコンテキストで元のメソッドを呼び出すOnを持たない新しいメソッドを作成します。

いいえ、$.proxyはjquery呼び出しです。jqueryが必要です。

1

私が通常typescriptとknockout jで行うもっとも簡単な解決策は、私がノックアウトから呼び出された関数をプロトタイプではなくコンストラクタで宣言していることです。だから、私は次のようにします:

export class ViewModel { 
     public users: knockout.koObservableArrayBase; 
     removeUser:(user: User) => void; 

     constructor() { 
      this.users = ko.observableArray([]); 
      this.removeUser = (user:User) => { 
       this.users.remove(user); 
      } 
     } 
} 
0

同じ問題が発生しました。適切なコンテキストを取得するには、クリックバインディングによって渡されるパラメータを使用できます。 クリックバインディングは、2つのパラメータ、つまりユーザーとクリックのjqueryイベントを渡します。

jqueryイベントを実行し、ko.contextFor()関数を使用すると、正しいコンテキストを取得できます。 data-bind="click: $root.MyFunc.bind($root)":代替は、あなたのビューモデルであることをthisの値を強制するためにはJavaScriptのbind機能を使用するバインディングを変更するにはクリックで

removeUser(user: User, clickEvent: any): void { 
    var self = ko.contextFor(clickEvent.srcElement).$root; 
    self.users.remove(user); 
} 
2

あなたの関数は次のようになります。

click binding仕様によって記載されているように$dataとクリックeventオブジェクトがまだノックアウトからMyFuncに引数として渡されることに注意してください。渡された引数をMyFuncに上書きする必要がある場合は、$rootの後にバインド関数に渡します。.bind($root, param1, param2)。技術的には、これらの引数は、[param1, param2, data, event]という引数を与えて、の先頭にの引数がKnockoutによって提供されます。

関連する問題