0

我有一个 Backbone.js 应用程序并正在尝试与 Backgrid 集成,但我无法理解我应该在哪里调用new Backgrid. 我尝试在渲染后在我的视图中调用它,但附加网格不起作用,因为实际上还没有渲染。这是一些代码:

SpreadsheetIndex.js.coffee

D3.Views.SpreadsheetsIndex = Support.CompositeView.extend
  initialize: (options) ->
    this.tables = options.tables
    this.resources = options.resources
    _.bindAll(this, 'render')

  render: ->
    this.renderTemplate()
    this.renderSpreadsheets()

    resources = this.resources

    this.tables.each (table) ->

      subset = resources.subcollection
        filter: (resource) -> 
          resource.escape('table_id') == table.escape('id')

      grid = new Backgrid.Grid
        columns: table.attributes.columns
        collection: subset

      $("#"+table.escape('id')).append(grid.render().$el);
    return this

  renderTemplate: ->
    this.$el.html(JST['spreadsheets/index']({ spreadsheets: this.tables }))

  renderSpreadsheets: ->
    self = this
    self.$('tbody').empty();

电子表格/index.jst.ejs

<% spreadsheets.each(function(spreadsheet) { %>
  <h4><%= spreadsheet.escape('name')%></h4>
  <div id='<%= spreadsheet.escape('id') %>'></div>
<% }) %>

问题是$("#"+table.escape('id'))选择器没有选择任何东西,因为模板还没有呈现。感觉就像我把它放在了错误的地方。我究竟做错了什么?

4

1 回答 1

0

我猜你想使用视图的@$方法而不是$将选择器本地化到视图的el

this.tables.each (table) =>
  #...
  @$("#"+table.escape('id')).append(grid.render().$el);

请注意,它->已经变成=>(为了获得正确的@/ this),它现在使用@$而不是$.


当我在这里时,你可以做一些其他的事情来让你的代码更符合概念:

  1. class D3.Views.SpreadsheetsIndex extends Support.CompositeView而不是 JavaScripty D3.Views.SpreadsheetsIndex = Support.CompositeView.extend
  2. 使用@代替this,例如@tables = options.table而不是this.tables = options.table
  3. +如果您认为它更干净,则可以使用字符串插值代替:

    @$("##{table.escape('id')}")
    
  4. 你很少需要bindAll,而不是_.bindAll(this, 'render')你可以定义renderrender: =>让绑定自动发生。

  5. 您很少需要var self = thisCoffeeScript 中的技巧,通常可以使用 a=>来代替。你不需要任何一个:

    renderSpreadsheets: ->
      self = this
      self.$('tbody').empty();
    

    你可以renderSpreadsheets: -> @$('tbody').empty()

于 2013-06-24T20:10:53.420 回答