javascript - 在 Backbone 模型中定义实例变量的正确方法是什么?

标签 javascript backbone.js coffeescript

我想知道我应该如何在 Backbone 模型中定义实例变量。这是我目前正在做的方式:

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

@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 [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()

然后,从刚刚执行的 View 来看 @model.columnNames

最佳答案

这是我在我的基础模型父类(super class)中所做的。这几乎与主干设计背道而驰,但我也讨厌使用 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("john@example.com").role("admin")

关于javascript - 在 Backbone 模型中定义实例变量的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10745257/

相关文章:

javascript - AngularJS 范围没有注意到变化

ruby-on-rails - Rails远程表单成功,但没有返回数据

javascript - php js函数时间间隔

javascript - Sequalizejs 向现有表添加偏执配置

typescript - 我可以声明模块在 Typescript 中全局可用吗?

javascript - requireJS 使用 require 加载文本

javascript - 使用 CoffeeScript 从对象数组中选择一个字段

javascript animate-ScrollTop 随机工作

javascript - 取消选中复选框应该删除附加的 html,但是

Backbone.js 仅创建第一个模型,然后在使用 Google 日历解析时将其余模型返回为未定义