Want to see the full-length video right now for free?
First create a serializer for TodoList
Add has_many todo_items as well
class TodoListSerializer < ActiveModel::Serializer attributes :id
has_many :todo_items end
Next we're going to create Backbone Collection and Model objects for todo items
For now simply create an empty TodoItem model
class App.Models.TodoItem extends Backbone.Model
The TodoItem collection class will only reference the TodoItem model
class App.Collections.TodoItems extends Backbone.Collection model: App.Models.TodoItem
Override our Backbone TodoList model's constructor
Create a todoItems attribute and assign an instance of the Backbone TodoItem collection object
constructor: -> @todoItems = new App.Collections.TodoItems([], todoList: this) super(arguments...)
In the parse method reset the todoItems attribute to the values passed in the data argument
parse: (data) ->
@todoItems.reset(data.body.todo_list.todo_items, parse: true)
delete data.body
data
Create a toJSON method to translate the data back to the format provided by the server
toJSON: ->
{
title: @get('title')
body:
type: 'todo_list'
todo_list:
todo_items: @todoItems.toJSON()
}
Now we need to create a TodoItemsIndex Backbone view
ul
todo-items
For now we'll leave the render method blank
class App.Views.TodoItemsIndex extends Backbone.View tagName: 'ul' className: 'todo-items'
render: => @$el.html('') this
Next we create a singular TodoItem Backbone view
todo-item
In the render method display the model's title
class App.Views.TodoItem extends Backbone.View className: 'todo-item'
render: => @$el.html(@model.get('title')) this
Once we're done with our TodoItem Backbone view we need to add some code to our TodoItemsIndex Backbone view
In the render method we want to iterate over our collection of TodoItems and render the TodoItem Backbone view for each item
render: => @$el.html('') @collection.forEach(@renderItem) this
To do this we need to add a method named renderItem
that takes a TodoItem
model as an argument
In the renderItem method we need to instantiate an instance of the TodoItem Backbone view and append the rendered view to the TodoItemIndex's DOM object
renderItem: (model) =>
view = new App.Views.TodoItem(model: model, tagName: 'li')
@$el.append(view.render().el)
Finally we need to override the TodoItemIndex Backbone view's initialize method to tell the object to rerender when an item is added to the collection, or when the collection is reset
initialize: -> @listenTo(@collection, 'add', @renderItem) @listenTo(@collection, 'reset', @render)
Now we return to our TodoList Backbone view
We pass the TodoList's model's todo_items as the TodoItemIndex's collection
initialize: -> @todoItems = new App.Views.TodoItemsIndex(collection: @model.todoItems)
Next we modify the render method to render the TodoItemIndex view we instantate in the initalizer
render: -> @$el.html(@todoItems.render().el) this
Finally we have to tell the TodoList Backbone view to remove the newly instantiated TodoItemIndex when anytime it gets removed to avoid a memory leak
remove: -> @todoItems.remove(arguments...) super(arguments...)
Now that we're printing out todo list items let's add some styles
Inside the .body class definition add a definition for the .todo-items class
.todo-items { padding: 0;
.todo-item { list-style: none; } }
Now we'll make the todo items in the list editable
Create a new todo item show template
app/assets/templates/todo\_items/show.jst.eco
Inside the template add a single text input