Как я могу использовать Coffeescript 'this' из jQuery $.bind()?

При использовании классов в Coffeescript я наткнулся на серьезную проблему, позвольте мне проиллюстрировать

class Bet
  constructor: () ->

  placeBet: ->
    $('#chips > div').bind 'click', ->
      amount = $(this).attr 'id'
      pile = $(this)
      switch amount
        when "ten" then this.bet pile, amount #This line causes a problem

  bet: (pile, amount) ->
    alert 'betting!'

При вызове this.bet возникает следующая ошибка:

Uncaught TypeError: Объект # не имеет метода 'bet'

Итак, в настоящее время метод экземпляра моего класса не вызывается, Как я могу правильно вызвать метод ставка моего класса, не сталкиваясь с этим селектором jQuery (что, как я полагаю, происходит сейчас)?

Спасибо вам заблаговременно!

Ответ 1

Попробуйте следующее:

class Bet
  constructor: () ->

  placeBet: ->
    that = this
    $('#chips > div').bind 'click', ->
      amount = $(this).attr 'id'
      pile = $(this)
      switch amount
        when "ten" then that.bet pile, amount #This line causes a problem

  bet: (pile, amount) ->
    alert 'betting!'

Ответ 2

Другим решением является использование жирной стрелки CoffeeScript в обработчике событий клика, тогда ваша область будет такой же, как если бы вы были внутри функции placeBet. Затем вы использовали бы e.currentTarget для получения ссылки на целевой объект вместо использования $(this)

class Bet
  constructor: ->

  placeBet: ->
    $('#chips > div').bind 'click', (e) =>
      target = $(e.currentTarget)
      amount = target.attr 'id'

      switch amount
        when "ten" then @bet target, amount #This line causes a problem

  bet: (pile, amount) ->
    alert 'betting!'

Ответ 3

Вы script превращаются в это:

var Bet;

Bet = (function() {

  function Bet() {}

  Bet.prototype.placeBet = function() {
    return $('#chips > div').bind('click', function() {
      var amount, pile;
      amount = $(this).attr('id');
      pile = $(this);
      switch (amount) {
        case "ten":
          return this.bet(pile, amount); //<< you cannot do this!!!
      }
    });
  };

  Bet.prototype.bet = function(pile, amount) {
    return alert('betting!');
  };

  return Bet;

})();

Вам нужна ссылка на _self, которая есть объект Bet:

class Bet
  constructor: () ->

  placeBet: ->
    _self = this
    $('#chips > div').bind 'click', ->
      amount = $(this).attr 'id'
      pile = $(this)
      switch amount
        when "ten" then _self.bet pile, amount #This line causes a problem

  bet: (pile, amount) ->
    alert 'betting!'