3

私は先週、coffeescript を標準とする新しい Play20 サイトをプログラミングしているので、coffeescript を書き始めました。クラスの getData 関数を 5 分ごとに更新したいのですが、setInterval 関数がクラスにバインドされません。setUpdateInterval() 関数がコンストラクター内から呼び出されるため、「this」オブジェクトにはまだ到達可能であるため、getData を初めて呼び出すときのみ。

しかし、最初の呼び出しの後、setInterval は Widget インスタンスとの接続を失い、 this.getData() 関数が何であるか (およびそれに到達する方法) を知りません。

誰かがそれを行う方法を知っていますか?

これが私のコードです:

class Widget
  constructor: (@name) ->
    this.setUpdateInterval()

  getData: ->
    console.log "get Data by Ajax"

  setUpdateInterval: (widget) ->
    setInterval( this.getData(), 3000000 )
4

3 に答える 3

7

ここで、Javascript マジックが必要になります。参照

class Widget
  constructor: (@name) ->
    this.setUpdateInterval()

  getData: ->
    console.log "get Data by Ajax"

  setUpdateInterval: (widget) ->
    callback = @getData.bind(this)
    setInterval( callback, 3000000 )

これはほとんどすべてのブラウザーで機能するため (どれがそうでないかを推測してください)、関数を別の方法でバインドする必要があります。コーヒースクリプトの魔法:

callback = => @getData
于 2012-05-09T12:18:23.997 に答える
3

問題は、関数への参照を渡すのではなく、関数を実行していることです。

さて、インスタンスのスコープも維持する必要があるようです。 doそしてそれ=>を助けることができます。

 setUpdateInterval: (widget) ->
    setInterval (do =>
      @getData), 3000000
    true

にコンパイルします

Widget.prototype.setUpdateInterval = function(widget) {
      var _this = this;
      setInterval((function() {
        return _this.getData;
      })(), 3000000);
      return true;
    };

コードが自己呼び出し関数を実行し、関数を返し、クロージャを作成してthis、コールバックのスコープにロックしていることに注意してください(として_this

また、ウィジェットをメソッドに渡す必要はなく(どこでも使用していない)、コンストラクターでこの関数を呼び出して間隔を設定することにも注意してください。何をするにしても、このメソッドを1回だけ呼び出します。関数の内容をコンストラクターに入れるだけです。

最後に、coffeescriptはすべての関数から最後のステートメントの値を返すので、trueそこにaをスローしますが、それは必要ないかもしれません。

于 2012-05-09T12:12:29.990 に答える
0

これはノードでも便利です。これは、タスの答えの変形です。

class Widget
  constructor: (@options = {}) ->
    @options.interval ?= 1000
    @setInterval()

  timer: ->
    console.log 'do something'

  setInterval: ->
    cb = @timer.bind @
    setInterval cb, @options.interval

w = new Widget()
于 2013-05-04T15:07:19.340 に答える