I have a Backbone.js app and am trying to integrate with Backgrid, but I am having trouble understanding where I should be calling new Backgrid
. I tried calling it in my view after things get rendered but appending the grid doesn't work because things aren't actually rendered yet. Here is some code:
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();
<% spreadsheets.each(function(spreadsheet) { %>
<h4><%= spreadsheet.escape('name')%></h4>
<div id='<%= spreadsheet.escape('id') %>'></div>
<% }) %>
The issue is that the $("#"+table.escape('id'))
selector does not select anything because the template hasn't rendered yet. It feels like I'm putting this in the wrong place. What am I doing wrong?
I'd guess that you want to use the view's @$
method to instead of $
to localize the selector to the view's el
:
this.tables.each (table) =>
#...
@$("#"+table.escape('id')).append(grid.render().$el);
Note that ->
has become =>
(to get the right @
/this
) and it now uses @$
instead of $
.
While I'm here, you can do a couple other things to make your code more ideomatic:
class D3.Views.SpreadsheetsIndex extends Support.CompositeView
instead of the JavaScripty D3.Views.SpreadsheetsIndex = Support.CompositeView.extend
.@
instead of this
, for example @tables = options.table
rather than this.tables = options.table
.You can use string interpolation instead of +
if you think it is cleaner:
@$("##{table.escape('id')}")
You rarely need bindAll
, instead of _.bindAll(this, 'render')
you could define render
as render: =>
to get the binding to happen automatically.
You rarely need the var self = this
trick in CoffeeScript, you can usually use a =>
instead. And you don't need either one here:
renderSpreadsheets: ->
self = this
self.$('tbody').empty();
you can just renderSpreadsheets: -> @$('tbody').empty()