I’m wondering how I should define instance variables inside a Backbone Model. This is the way I’m currently doing it:
class GeneSet extends Backbone.Model
initialize: (parsedGenes)->
@set parsedGenes: parsedGenes
@set geneNames: (gene.gene_name for gene in @get("parsedGenes"))
@set geneIds: ("gene_#{id}" for id in [1..@get("parsedGenes").length])
@set columnNames: @getColumnNames()
@set columnGroups: @getColumnGroups()
@set geneExpressions: @getGeneExpressions()
@set groupedGeneExpressions: @getGroupedGeneExpressions()
@set extent: @getExtent()
clusterColor: ->
d3.scale.category20()()
getGeneNameById: (geneId)->
@get("geneNames")[@get("geneIds").indexOf(geneId)]
getColumnGroups: ->
_.uniq((@get("columnNames")).map((columnName)->
columnName.split("_")[0]
))
getExtent: ->
expressions = _.flatten(@get("geneExpressions").map (geneExpression)->
geneExpression.map (item)->
item.y
)
d3.extent(expressions)
getColumnNames: ->
Object.keys(@get("parsedGenes")[0]).filter (columnName) ->
!columnName.match(/cluster/) && isNumber(parsedGenes[1][columnName])
getGeneExpressions: ->
@get("parsedGenes").map (gene) =>
@get("columnNames").map (columnName) ->
x: columnName
y: +gene[columnName] # make numeric
This seems a little redundant to do @set columnGroups: @getColumnGroups() and having to get every variable using @get("...") seems kind of verbose (I wish I could do @variableName). My question is, is this the right way of using models and instance variables or am I doing it wrong? Also, is there any difference to doing this?:
class GeneSet extends Backbone.Model
initialize: (parsedGenes)->
@parsedGenes = parsedGenes
@geneNames = (gene.gene_name for gene in @parsedGenes)
@geneIds = ("gene_#{id}" for id in [1..@parsedGenes.length])
@clusters = (gene.cluster for gene in @parsedGenes)
@descriptions = (gene.description for gene in @parsedGenes)
@columnNames = @getColumnNames()
@columnGroups = @getColumnGroups()
@geneExpressions = @getGeneExpressions()
@groupedGeneExpressions = @getGroupedGeneExpressions()
@extent = @getExtent()
And then, from the view just doing @model.columnNames
Here’s what I do in my base model superclass. It’s pretty much against the backbone design, but I too hate using
getandsetand I want real methods behind all attribute access. So I do some metaprogramming and generate named get/set methods. So instead of having to do:I can just do
Here’s my base code to do this automatically for any arbitrary
attributesobject.Note this was written on a backbone version old enough to not support
set("key", "value"). If I were to update it, I’d probably use that variant. Note since thesetflavor returns the object, they are chainable:model.name("John").email("john@example.com").role("admin")