Want to see the full-length video right now for free?
Add an array called AllNotes
to the ScratchPad
initialize method
Populate the AllNotes array with the values from our db seed file and manually add an id attribute
window.ScratchPad = Models: {} Collections: {} Views: {} Routers: {} initialize: -> @AllNotes = [ { id: 1, title: 'make a second todo item', complete: true }, { id: 2, title: 'Make another todo list', complete: false }, { id: 3, title: 'DSICO PARTY!', complete: false } ] new @Routers.ScratchPadRouter Backbone.history.start(pushState: true)
Create an empty Notes Backbone view at
app/assets/javascripts/views/notes.js.coffee
class App.Views.Notes extends Backbone.View
In order to make our view accessible we'll modify the index route in our Backbone router
After creating our instance of the Backbone view we need to render it and
appened it to a DOM element we'll use a div with the id container
class App.Routers.ScratchPadRouter extends Backbone.Router routes: '': -> 'index' '/notes/:id': 'showNote'
index: -> view = new App.Views.Notes(collection: App.AllNotes) $('#container').html(view.render().el)
showNote: (id) -> alert("You requested the note with the id of #{id}")
Next we need to add a render method to our Notes Backbone view
class App.Views.Notes extends Backbone.View
render: ->
@$el.html('Hello from the Notes view')
this
Now add a div to the application.html.erb file in the layouts folder with the id of 'container'
Backbone template options
_.template
. It works
a lot like ERB, however you call it like
_.template('<h1><%= title %></h1>')(title: 'Hello World')
Set the new template method on the Notes Backbone view to the value returned from a
hash called JST when it recieved the path to the view as a key template: JST['notes/index']
class App.Views.Notes extends Backbone.View template: JST['notes/index']
render: -> @$el.html('Hello from the Notes view') this
Create a file named app/assets/templates/notes/index.jst.eco
@notes.each
to for note in @notes:
Replace the call to link_to
with a hard coded anchor tag
Now we need to revisit the Notes Backbone view and pass in the notes we want our template to render
@$el.html(@template(notes: @collection)); this
Notice we use the collection attribute
class App.Views.Notes extends Backbone.View template: JST['notes/index']
render: -> @$el.html(@template(notes: @collection)) this
If we refresh our browser we see that our view is working, but the link is not yet async
In order to make the link function asynchronously we need to do the following
Define an event on click by adding of an anchor tag in the view. This is achieved by adding a value to the hash table whose key is 'click a' and value is either a function or a method name in the view
events: 'click a': 'showNote'
Now we need to define the showNote
method
Your event Notes Backbone view should look like this
showNote: (e) -> $this = $(e.currenttarget) backbone.history.navigate($this.attr('href')) false
If we go back to the browser and click the title link you'll notice the page doesn't change, but the URL is modified
This is caused by Backbone defaults. In order to make backbone attempt to route the url you have to pass trigger: true to the navigate method
showNote: (e) -> $this = $(e.currentTarget) Backbone.history.navigate($this.attr('href'), trigger: true) false
If you push the back and forward buttons you'll notice history still works as well
pushState
and popState
Now we will create a view for a single Note
Modify the router so the showNote method creates an instance of the new view with a @model from the AllNotes collection based on the id passed in the url
class App.Routers.ScratchPadRouter extends Backbone.Router routes: '': -> 'index' '/notes/:id': 'showNote'
index: -> view = new App.Views.Notes(collection: App.AllNotes) $('#container').html(view.render().el)
showNote: (id) -> model = App.AllNotes[id - 1] view = new App.Views.EditNote(model: model) $('#container').html(view.render().el)
There's not really any reason to have a 'show' action for a single note, so we're going to combine show and edit
In the EditNote Backbone view change the tag that the view will render from a div to
a form with the following tagName: 'form'
tagName: 'form'
Add a new template at app/assets/template/edit.jst.eco and build out a simple form
<%= @note.content %>
Add 'submit' to the events hash
In the submit event handler pull the values out of the form manually
events: 'submit': 'saveModel'
We also need to add a saveModel
method
We use the set
method to set the model's attributes
saveModel: (e) -> @model.set title: @$('.title').val() content: @$('.content').val() Backbone.history.navigate('/', trigger: true) false
In it's current state the values in the browser will update, but the values are not being persisted to the database.
Commit!