2012-05-24 106 views
1

我想知道如何在骨幹模型中定義實例變量。這是目前我做的方式:在骨幹模型中定義實例變量的正確方法是什麼?

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 [[email protected]("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 

這似乎有點多餘做@set columnGroups: @getColumnGroups()且獲得使用@get("...")每個變量似乎有點冗長(我希望我能做到@variableName)。我的問題是,這是使用模型和實例變量的正確方式還是我做錯了?另外,有沒有這樣做有什麼區別?:

class GeneSet extends Backbone.Model 
     initialize: (parsedGenes)-> 
      @parsedGenes = parsedGenes 
      @geneNames = (gene.gene_name for gene in @parsedGenes) 
      @geneIds = ("gene_#{id}" for id in [[email protected]]) 
      @clusters = (gene.cluster for gene in @parsedGenes) 
      @descriptions = (gene.description for gene in @parsedGenes) 
      @columnNames = @getColumnNames() 
      @columnGroups = @getColumnGroups() 
      @geneExpressions = @getGeneExpressions() 
      @groupedGeneExpressions = @getGroupedGeneExpressions() 
      @extent = @getExtent() 

,然後從只是在做@model.columnNames

+0

如果您執行第二種方式,您如何觀察屬性更改?如果描述更改,則不能觀察描述。唯一的選擇是使用ES5 Object.defineProperty,但是與舊版瀏覽器不兼容。而且它並不適合那種好的骨幹「方式」。 – mpm

+0

我看,有人在這裏:http://srackham.wordpress.com/2011/10/16/getters-and-setters-for-backbone-model-attributes/ – nachocab

+0

我沒說你不能,我說如果你有20個道具......我想你可以創建一個輔助功能。 – mpm

回答

3

認爲這是我在我的基礎模型做超。這很大程度上違背了主幹設計,但我也討厭使用getset,並且我想要所有屬性訪問背後的真實方法。所以我做了一些元編程並生成了命名的get/set方法。因此,而不是不得不做:

model.get("name") 
model.set("name", "Tom") 

我可以做

model.name() 
model.name("Tom") 

這裏是我的基本代碼的任意attributes對象自動執行此操作。

addConvenienceMethods = -> 
    for prop, value of this.attributes 
    ((prop) -> 
     #Define a setter/getter function 
     this[prop] = (newValue...) -> 
     if newValue.length 
      obj = {} 
      obj[prop] = newValue[0] 
      this.set obj 
      return this 
     else 
      return this.get prop 
     #Use the newly-defined setter function to store the default value 
     this[prop](value) 
    ).call(this, prop) 

########## Base Model Superclass ########## 
class exports.Model extends Backbone.Model 
    initialize: -> 
    addConvenienceMethods.call this 

注意這是寫在主幹版本夠大了,不支持set("key", "value")。如果我要更新它,我可能會使用該變體。請注意,由於set風味返回對象,因此它們是可鏈接的:model.name("John").email("[email protected]").role("admin")

相關問題