2016-11-23 9 views
1

jqueryとModel View ViewModelを使い始めましたが、これをEvent Handler Attachment:on()で使用する際に問題が発生しました。メソッドへのアクセス中に問題が発生しました

var TicTacToeModel = function() { 
     Observable.call(this); 
     this.grid = new Array(3); 
     for (let i = 0; i < this.grid.length; ++i) { 
      this.grid[i] = new Array(3); 
     } 
    }; 
//Some prototype function 
//... 

私は最初のクラスに依存し、DOMの操作とゲームのグラフィック部分を管理する別のクラス、TicTacToeControllerを持っている:

私の最初のクラスは、メモリ内に三目並べゲームを操作TicTacToeModelです
var TicTacToeController = function(game, selector) { 
     this._element = $(selector); 
     this._model = game; 
     this._template = Handlebars.compile(view); 
     this.addListeners(); 
     this.render(); 
    }; 

(ゲームの宣言:game = new TicTacToeModel();

だから私の第二のクラスでは、私はこの機能を持っている:

TicTacToeController.prototype.addListeners = function() { 
    this._model.on('change', this.render, this); 
    this._model.play(0,0);//works 
    this._element.on('click', "td", function() { 
     this._model.play(0,0);//doesn't work 
    }); 
}; 

セル(0,0)でplay()関数を呼び出したいと思います(関数playはメモリ内のゲームを更新します)。グラフィックインターフェイスでセルをクリックすると再生できません.on()。しかし、これは.on()関数の外で動作しているようですので、問題の原因となるのは、thisの悪い利用を想定しています。

答えて

1

このようにbindを使用する必要があります。

変更この:

this._element.on('click', "td", function() { 
    this._model.play(0,0);//doesn't work 
}); 

へ:

this._element.on('click', "td", function() { 
    this._model.play(0,0); //should now work 
}.bind(this)); 
+0

あなたの答えをありがとう、それはうまく動作しますが、私はそのような関数にいくつかのjqueryを追加する: 'TicTacToeController.prototype.addListeners = function(){ this._model.on( 'change'、this.render、this ); this._element.on( 'click'、 "td"、function(){ $(this).addClass( "case"); $(this).html( "X"); this._model。再生(0,0); //動作しません } .bind(this)); }; 'jqueryは考慮されません。修正する考えはありますか? – Lodec

+0

「jqueryは考慮されていませんが、あなたは '$(this.)の代わりに' $(this._element)... 'を試しましたか? – Jack

+0

'$(this._element)'は私のグリッド全体を変更するので動作しませんが、 'this._element.on( 'click'、" td "、function(event){なぜなら、これは.on()関数の "td"要素を表していますか? – Lodec

0

あなたは同じスコープ内ではありませんが、それはplayメソッドを呼び出すときに、あなたが採用されているのと同じ、この変数ではありません。 汚い回避策は

let _model = this._model 
this._element.on('click', "td", function() { 
     _model.play(0,0);//work! 
    }); 

ことができるが、それは汚い回避策だと述べているように、多分他の誰かが説明できるが、基本的に、これはメモリリークを発生さだと思います。たぶんソリューションは一種の、同じクラスのメソッドを使用して、クリックメソッドにインスタンスを渡すために、次のようになります。

TicTacToeController.prototype.click = function() ... 
... 
this._element.on('click', "td", this.click); 

が、これはトリックを行うべきだと思いますが、私はJSの専門家ではない認めなければなりません。

+1

私はこの汚れた回避策を使うことも考えましたが、私は知っていました私の問題を解決する良い方法があったことを知っている^^。 – Lodec

関連する問題