I woud like to define flightjs components with CoffeeScript classes instead of functions but it seems to not be possible because flight ignores objects' prototypes. I can't write:
define ['flight/component'], (defineComponent) ->
class MyDropdown
constructor: () ->
@defaultAttrs #attrs
@after 'initialize', () ->
#doSmth
func1: (evt, data) ->
func2: (evt, data) ->
return defineComponent MyDropdown
Instead of
define ['flight/component'], (defineComponent) ->
return DefineComponent () ->
this.func1 = (evt, data) ->
this.func2 = (evt, data) ->
this.defaultAttrs #attrs
this.after 'initialize', () ->
#doSmth
Because first sample of code binds func1 and func2 to MyDropdown prototype
MyDropdown.ptototype.func1
So only workaround I found out is to create 'proxy' class to bind prototypes methods in constructor when it's already flight component:
define [], () ->
class FlightComponent
constructor: (childClass) ->
# constructor is ommited because I don't want to override component's constructor
@[name] = func if name isnt 'constructor' for name, func of childClass.prototype
return FlightComponent
define ['flight/component', 'js/FlightComponent'], (defineComponent, FlightComponent) ->
class MyDropdown extends FlightComponent
constructor: () ->
super MyDropdown
@defaultAttrs #attrs
@after 'initialize', () ->
#doSmth
func1: (evt, data) ->
func2: (evt, data) ->
return defineComponent MyDropdown
I think it's awkward that I have to call parent constructor with class as parameter to make it works with flight API. I coud get over parent class and just write code inside at the begining of the constructor but I find inheritance more flexible (fe. if I'll add DataComponent and Component classes in future).
So I'm wondering is there any better way to use full futures of CoffeeScript with Twitter Flight?
It seems to be counterintuitive that flight does not allow to bind methods to object prototype... Or do I miss something?
Edit
Best solution I found out for now:
define ['flight/component', 'js/mixin1', 'js/mixin2'], (defineComponent, withA, withB) ->
class MyDropdown extends defineComponent withA, withB
constructor: ->
# yay, got access to mixins, component and MyDropdown's prototype methods
Best solution I found is to simply extend component with mixins.
js/withAB
define ['flight/component', 'js/mixins/mix1', 'js/mixins/mix2'], (defineComponent, withA, withB) ->
defineComponent withA, withB
js/myComponent
define['js/withAb'] (componentWithAB) ->
myComponent extends componentWithAB
constructor: ->
@defaultAttrs
name: 'selector'
@after 'initialize', ->
@on 'smth', 'event', @method1
method1:->
# code
In code
require 'js/myComponent', (myComponent) ->
myComponent.attachTo 'selector'
This way myComponent is class that extends flight's api component and has both mixinx methods. Another component may easily extend this class, override some methods and define it's own constructor.
Defining component as class instead of function helps keeping components distinct from mixins. Also code structure is better in class because all logic that happens after object initialization (not component initialization!) is placed in constructor while all functions are binded to prototype.
In my real life app instead of bootstrap file js/withAB I've written function that takes mixins (or nothing) as arguments and returns component instance with them mixed in.