CoffeeScript send hashed params to constructor - coffeescript

I want to create objects in Ruby style with CoffeeScript. So I want to do something like
class A
constructor: (#params) ->
a = new A {send: true, name: "fit"}
a.send #true
Is there any "standard" way to do this?

There is no way to do it directly. You could define a base class that has code to do it, like such
class Base
constructor: (props) ->
for key, value of props
#[key] = value
class Extend extends Base
constructor: (props) ->
super props
alert "#{#key1}, #{#key2}"
e = new Extend 'key1': 'val1', 'key2': 'val2'
alert "#{e.key1}, #{e.key2}"
See it working here

Related

ReactJS dynamically call custom class

I am trying to setup a way to create form objects dynamically from some json values. Essentially, I have in my json the form object type and properties. I pass that type to a FormInput class that then calls the custom class containing the actual form object. My problem right now is that when I pass in the custom class name "TextInput" (this.props.formElementType) React just creates an element called 'textinput' instead of calling the class. It doesn't appear to like passing in a string, but wants just the classname. Essentially,...
TextInput = React.createClass({...})
...
FormItem = React.createElement(<TextInputPassedAsAString>, {...})
I am not sure if I can call a custom class this way or not, by passing a string. I need help with this implementation or a better idea as I am relatively new to React.
Below is all the relevant code starting with the children ending with the final render block. Please excuse the pseudo coffeescript.
TextInput
TextInput = React.createClass
handleChange: (event)->
this.setState
value: event.target.value
render: ->
React.createElement('label', {
value: this.props.formElementLabel
})
React.createElement('input', {
id: this.props.formElementID,
type: 'text'
})
module.exports = TextInput
FormElement
FormElement = React.createClass
render: ->
R.div(null,
React.createElement(this.props.formElementType, {
formElementID: this.props.formElementID,
formElementLabel: this.props.formElementLabel
})
module.exports = FormElement
The initial call/final render
React.createElement(FormElement, {
formElementType: 'TextInput',
formElementID: 'firstFormElement',
formElementLabel: 'First text input'
})
Well, the best way, easiest to reason about, etc. is probably to require TextInput in the module that's doing your final render. Create it there, passing in the other props to it, and then pass this created component to FormElement rather than passing the string representation of the component.
One way to do this more dynamically would be to have have a module that exports each dynamic component as a property/method on the export. Something like:
module.exports = {
TextInput: ...
}
Then when you're rendering you could pass in something like this:
myImports[json.formElementType]

create class instance from class name as string and pass in argument

From a string I'm trying to instantiate a class (my marionette view). I found a way that works but this way has a problem where I can't actually pass a parameter to the instantiated class.
It seems when I call typeMapping[viewType] it's actually returning me Show.OneNode() instead of just Show.OneNode
class Show.TwoNode extends App.ItemView
template: "templates/two"
class Show.OneNode extends App.ItemView
template: "templates/one"
class Show.Layout extends App.Layout
onShow: =>
typeMapping = {
one: Show.OneNode
two: Show.TwoNode
}
viewType = "one"
view = new typeMapping[viewType]
model: #model
again, I would have rather made this a comment, but hey that's life. Have you tried wrapping your values from your key/value pairs in quotes to force them as strings?
typeMapping = {
one: "Show.OneNode",
two: "Show.TwoNode"
}

Spine.js get associated controller from element

I got an html-element aside.sidebar with an associated spine.js controller.
class App.Sidebar extends Spine.Controller
tag: 'aside'
className: 'sidebar'
how do i get the controller from the element? something like this:
con = $("aside.sidebar").spineController().someControllerMethod()
I'm using jquery + spine.js.
I've looked through the controller source code and it doesn't look like there is a built-in way to access the controller from the element (https://github.com/spine/spine/blob/dev/src/spine.coffee#L482). What I do is make a global variable to hold the controller so that I can access it from other places:
app = new App()
# inside of App constructor:
#foo_widget = new App.FooWidgetController()
# from other non-spine code:
app.foo_widget.method()
Another option would be to do the association yourself using jquery's data() method:
class App.FooWidgetController
constructor: ->
super
#el.data 'controller', this
# from other code:
$('#widget').data('controller').method()

CoffeeScript mixin doesn't work

I found this example of mixins in coffeescript faq but it seems like it doesn't work.
Am I missing something here?
extend = (obj, mixin) ->
for name, method of mixin
obj[name] = method
include = (klass, mixin) ->
extend klass.prototype, mixin
class Button
onClick: -> alert "click"
class Events
include Button, Events
(new Events).onClick()
# => Uncaught TypeError: Object #<Events> has no method 'onClick'
fiddle
You are missing the fact that onClick is defined on the prototype of Button,
and that you did not set the arguments with the right order in the include function
extend = (obj, mixin) ->
for name, method of mixin
obj[name] = method
include = (klass, mixin) ->
extend klass.prototype, mixin
class Button
onClick: -> alert "click"
class Events
include Events,Button.prototype
(new Events).onClick()
see the "fiddle"
So the mixin snippet works pretty well.

Call static method in constructor — CoffeeScript

Say I'm declaring a class Game.
class #Game
constructor: ->
#id = Game.generateNewGameId() # <---
player1: null
player2: null
#generateNewGameId: -> "blahblah23"
Here, I'm using generateNewGameId as Game.generateNewGameId().
Is this the right way or is there a better way? I've tried using this::generateNewGameId() but the scope's different.
If you really want generateNewGameId to be a class method then you can use #constructor to get at it:
Returns a reference to the Object function that created the instance's prototype. Note that the value of this property is a reference to the function itself [...]
So something like this:
class Game
constructor: ->
#id = #constructor.generateNewGameId()
#generateNewGameId: ->
"blahblah23"
Note that this will do The Right Thing if you subclass Game:
class C extends Game # With an override of the class method
#generateNewGameId: ->
'pancakes'
class C2 extends Game # or without
Demo (open your console please): http://jsfiddle.net/ambiguous/Vz2SE/
I think the way you are accessing it is OK. You can also do #constructor.generateNewGameId() if you don't want to write Game.generateNewGameId() for some reason, but i'd prefer the later. Update: as #mu is too short mentions, the #constructor allows you to get the constructor of the instance, which can be differ from Game (in a subclass) so it has greater flexibility; if that flexibility is required in this case, definitely go for that :)
If the generateNewGameId function will not be accessed from outside the Game class, you can use a private function instead of a class method:
class #Game
gameIdCounter = 0
generateNewGameId = -> gameIdCounter++
constructor: ->
#id = generateNewGameId()
player1: null
player2: null
console.log (new Game).id # -> 0
console.log (new Game).id # -> 1
Example at coffeescript.org.
There both gameIdCounter and generateNewGameId are private variables inside the Game class.