I’m trying to create a basic version of this example in CoffeeScript: http://davidsulc.com/blog/2012/04/15/a-simple-backbone-marionette-tutorial/. All the dependencies are declared as .coffee files in the order I write them (in the body), and jQuery + Underscore + Backbone + Marionette are in the head.
I have a model, thing.coffee
$ ->
console.log 'load model'
class Thing extends Backbone.Model
defaults:
myValue: null
initialize: ->
console.log 'new thing'
window.Thing = Thing
My first hiccup is with scoping: if I don’t declare window.Thing, the next file (the collection of Things, can’t find the model Thing, and so on. What am I doing wrong there?
I have a collection, things.coffee
$ ->
console.log 'load collection'
class Things extends Backbone.Collection
model: Thing
window.Things = Things
I have a Marionette view, thing_view.coffee
$ ->
console.log 'load composite model view'
ThingView = Backbone.Marionette.ItemView.extend(
template: '#template-thing'
tagName: 'tr'
)
window.ThingView = ThingView
I have a Marionette view, things_view.coffee
$ ->
console.log 'load composite collection view'
ThingsView = Backbone.Marionette.CompositeView.extend(
tagName: 'table'
id: 'things'
template: '#template-things'
itemView: ThingView
appendHtml: (collectionView, itemView) ->
collectionView.$('tbody').append itemView.el
)
window.ThingsView = ThingsView
I have an application myapp.coffee
$ ->
console.log 'load app'
# Load default data
thingsCollection = new Things([
new Thing(myValue: 'uno'),
new Thing(myValue: 'dos')
])
data:
thingsCollection: thingsCollection
# Create application, specify default layouts
MyApp = new Backbone.Marionette.Application()
MyApp.addRegions singleRegion: '#content'
# On application init...
MyApp.addInitializer (data) ->
console.log 'Init application...'
thingsView = new ThingsView(collection: data.thingsCollection)
MyApp.singleRegion.show data.thingsView
# Start application
MyApp.start data
My html file looks like:
<div id="content">
<script type="text/template" id="template-things">
<thead>
<tr class='header'>
<th>myValue</th>
</tr>
</thead>
<tbody>
</tbody>
</script>
<script type="text/template" id="template-thing">
<td><%= myValue %></td>
</script>
</div>
Following the console.log:
load model
load collection
load composite model view
composite collection view
load app
Init application...
Uncaught TypeError: Cannot call method 'render' of undefined
So, needless to say I’m confused as to what is going on – I’m sure theres tons of things wrong here, so please help!
The CoffeeScript compiler wraps each file in a self-executing function so
Thingis local to the wrapper unless you forcibly globalize it by putting it inwindow.I think your real problem is right here:
You create a
ThingsViewand store it inthingsView. But then you try to passdata.thingsViewtoMyApp.singleRegion.showbut there’s nothing indata.thingsViewso you get a complaint when something inside Marionette tries toview.render(). I think you want this:or this:
depending on what this
dataobject is all about.