Matteo Pagliazzi
Matteo Pagliazzi

Reputation: 5260

CoffeScript class and binding

I have a class in CS:

class Model
  constructor: (objectParams) ->
    @object = ##object
    ###constructor

  baseObject: => {}
  validate: ko.computed =>
    console.log ko.toJS @object

The problem is with 'validate' it is a prototype property where the binding context of the ko.computed function should be the constructor but instead gets compiled to this:

Model.prototype.validate = ko.computed(function() {
  return console.log(ko.toJS(Model.object));
});

I want it to be binded to the constructor but the fat arrow => seems to be working only this way:

property: () =>

and this way it won't work

  validate: =>
    ko.computed => console.log ko.toJS @object

because ko.computed can't be defined inside a function

how can i solve?

Upvotes: 1

Views: 150

Answers (3)

robkuz
robkuz

Reputation: 9934

Binding your function to the instance and "preprocessing" it works like this

pipe = (fn)->
    return ->
        fn.apply(@, arguments)


class A
    foo: pipe -> @bar()
    bar: -> ...

from your pipe function (in your case ko.computed) return another function that wraps your initial function and calls it via .apply.

No need for the fat arrow as your are calling apply with @

Upvotes: 1

epidemian
epidemian

Reputation: 19219

I think robkuz identified the problem correctly. The solution should be to set the validate property inside the constructor:

class Model
  constructor: (objectParams) ->
    @object = ##object

    @validate = ko.computed =>
      console.log ko.toJS @object

Upvotes: 1

robkuz
robkuz

Reputation: 9934

if you "advise" a function before associating it with a class (the prototype) there will be no binding to the instance that usually happens with using the fat arrow.

class A
    foo: advise => @someMethod()

The intermediary advise function disconnects the CS compiler so that its not clear what you want to do and so that there is no call to

this.foo = __bind(this.foo, this); 

in the constructor.

However if you do use your "advise" function within a method definition then CS will create a closure for you and you will have access to the instance

class A
    foo: ->
         advise => @someMethod()

This will generate

A.prototype.foo = function() {
    var _this = this;
    return advise(function() {
       return _this.someMethod();
    });
};

The important thing here is the definition of "var _this = this;" which than will be used within your inline function definition.

Hope this helps.

Upvotes: 0

Related Questions