Reputation: 13195
I'm a Ruby programmer trying to create a small JavaScript library.
As I'm no big JavaScript expert I'm helping myself with CoffeeScript, fighting my way through a rather unknown territory.
The idea:
I want to create several small JavaScript widgets, all of which share some small pieces of functionality.
The shared functionality and config is in the Base
class. Every widget has its own class that inherits from Base
and can set its own config (and even overwrite configs of Base
).
Finally, when a widget is instantiated, it can be passed an option hash, itself overwriting the default options of the widget.
It looks like this so far:
@Adg = {}
class Adg.Base
config =
debugMessage: false
hiddenCssClass: 'visually-hidden'
# Constructor. Should not be overridden; use @init() instead.
#
# - Arg1: The DOM element on which the script should be applied (will be saved as @$el)
# - Arg2: An optional hash of options which will be merged into the global default config
constructor: (el, options = {}) ->
@config = config
@$el = $(el)
for key, val of options
@config[key] = val
@init()
# Dummy, must be overridden in inheriting classes.
init: ->
throw 'Classes extending App must implement method init()!'
class Adg.Autocomplete extends Adg.Base
config =
suggestionsContainer: 'fieldset'
suggestionsContainerLabel: 'legend'
alertsContainerId: 'alerts'
init: ->
# Merge config into existing one
for key, val of config
@config[key] = val
This works, but feels clumsy to me:
constructor
that must not be overridden by inheriting classes (I add an init()
method as a substitute)Upvotes: 0
Views: 100
Reputation: 26758
I believe the following will do what you are looking for:
@Adg = {}
class Adg.Base
@config =
debugMessage: false
hiddenCssClass: 'visually-hidden'
constructor: (el, options = {}) ->
@config = Object.assign {}, Adg.Base.config, options
@$el = $(el)
class Adg.Autocomplete extends Adg.Base
@config =
suggestionsContainer: 'fieldset'
suggestionsContainerLabel: 'legend'
alertsContainerId: 'alerts'
constructor: (el, options={}) ->
super(el, Object.assign({}, options, Adg.Autocomplete.config))
There are a couple changes I made:
@config
on Adg.Base
is read using Adg.Base.config
.super
to call the parent constructor from the child's.Object.assign
to merge hashes.Note that if you're using Coffeescript 2 (uninstall coffee-script and install coffeescript@next package), you can use the spread operator instead of Object.assign:
@config = {Adg.Base.config..., config...}`
Upvotes: 1