mpiccolo
mpiccolo

Reputation: 672

Coffeescript converting function to class

How can I port this function to using the coffeescript class syntax?

App.PurchaseOrder = (uid) ->
  binder = new App.DataBinder(uid, "purchase-order")

  # Abstract all this out
  purchase_order =
    attributes: {}

    # The attribute setter publish changes using the DataBinder PubSub
    set: (attr_name, val) ->
      @attributes[attr_name] = val
      binder.trigger uid + ":change", [
        attr_name
        val
        this
      ]
      return

    get: (attr_name) ->
      @attributes[attr_name]

    _binder: binder

  # Subscribe to the PubSub
  binder.on uid + ":change", (evt, attr_name, new_val, initiator) ->
    purchase_order.set attr_name, new_val  if initiator isnt purchase_order
    return

  purchase_order

Something along the lines of this however this will not work because @attributes is not defined in the binder.on in the constructor.

class App.PurchaseOrder
  constructor: (@id) ->
    @binder = new App.DataBinder(@id, "purchase-order")
    @attributes = {}

    # Subscribe to the PubSub
    @binder.on @id + ":change", (evt, attr_name, new_val, initiator) ->
      @attributes.set attr_name, new_val  if initiator isnt @attributes
      return

  # The attribute setter publish changes using the DataBinder PubSub
  set: (attr_name, val) ->
    @attributes[attr_name] = val
    @binder.trigger @id + ":change", [
      attr_name
      val
      this
    ]
    return

  get: (attr_name) ->
    @attributes[attr_name]

Upvotes: 0

Views: 65

Answers (2)

james emanon
james emanon

Reputation: 11807

how about this:

# Subscribe to the PubSub
@binder.on @id + ":change", ((evt, attr_name, new_val, initiator) -> 
    @attributes.set attr_name, new_val  if initiator isnt @attributes ).bind @
return

Upvotes: 0

Kuba Jagoda
Kuba Jagoda

Reputation: 5547

If you do something like this

@binder.on @id + ":change", (evt, attr_name, new_val, initiator) ->
  @attributes.set attr_name, new_val  if initiator isnt @attributes
  return

then it means that this function will be invoked in global context or in the context of e.g. event object, but the point is that this may not point to the object you want. Instead of -> use =>

@binder.on @id + ":change", (evt, attr_name, new_val, initiator) =>
  @attributes.set attr_name, new_val  if initiator isnt @attributes
  return

then this inside the callback will be bound statically, in this example to the instance of your class.

Upvotes: 1

Related Questions