Reputation: 34347
So, I have a standard class that is extended by child classes. In some cases, I'm passing what child class to use through jQuery as a option instead of using the default standard class.
Example:
jQuery('img').myPlugin();
Calls
New mainClass(arg1, arg2)
While
jQuery('img').myPlugin({classToUse : 'myExtendedClass'});
Calls
New myExtendedClass(arg1, arg2)
Here's the code that works, but it is ugly in so many ways. How can we do this properly? Here @settings is a simple object, and @settings.classToUse is a string that's passed.
@NewClass = eval("new #{@settings.classToUse}(this.$element, this.settings)")
The following does not work and returns a string error:
@Framer = new @settings['classToUse'](this.$element, this.settings)
A clipped version of the full source code is below. Any errors in the logic are a result of clipping the code as the code in its current state is 100% functional.
You can also see the code compiled here.
class mainClass
constructor: (@framedObject, @options) ->
doSomething: ->
alert('something')
class myExtendedClass extends mainClass
doSomething: ->
alert('somethingDifferent')
class anotherExtendedClass extends mainClass
doSomething: ->
super
alert('Woah!')
$ ->
$.plugin = (element, options) ->
@settings = {classToUse : 'myExtendedClass'} #built by merging defaults and options
@init = ->
@mainClass = eval("new #{@settings.classToUse}(this.$element, this.settings)")
@init()
this
$.fn.mediaFrame = (options) ->
return this.each ->
plugin = new $.plugin this, options
Upvotes: 0
Views: 323
Reputation: 5515
How about something like:
class Border
constructor: (@options) ->
class RedBorder extends Border
constructor: (@options) ->
class BlueBorder extends Border
constructor: (@options) ->
borders =
Default: Border
Red: RedBorder
Blue: BlueBorder
$.plugin = (element, options) ->
@mainClass = new borders[@settings.class || 'Default'](@settings)
Upvotes: 3
Reputation: 9934
your second approach will fail as you cant instantiate a "String"
@Framer = new @settings['classToUse'](this.$element, this.settings)
also there seems to be an error as you are using "type" instead of "classToUse"
The easiest way to would seem to simply put the class-object into the hash that you give to jQuery
jQuery('img').myPlugin({classToUse : redBorder});
In this example assuming that redBorder is the class name.
Upvotes: 0