At this stage I would like to start managing each book as a model, calling a function whenever book names are changed (just an alert in the function for proof of concept), and then calling a URL to sync changes to the model with my database.

Can anyone point me in the right direction for a way to do the above using existing html on a page?

Is your question about if you need to change your HTML for that purpose? If so: not really. Or do you want the JS?
–
Bernhard VallantJul 21 '11 at 11:52

@lazerscience - I just want to know if it is possible to create views from exisiting html (rather than pulling data, creating html using data+template and the injecting into the page) - and how I would do that? In the example above would I need to create a loop (I'm using jQuery) and create a view for every book element?
–
calumbrodieJul 21 '11 at 11:55

3 Answers
3

Backbone's views are always bound to a specfic html element (the view's attribute el). You could have something like a BookCollectionView bound to ul#bookCollection and a BookView bound to li.book, which should be fine with your current template structure.

You can map a Book model to a view using a url to the model. If the model is fetched from that url and you have defined an event binding for the model change, the according view should refresh with the new model data. Same applies for the collection's url and a collection of books.

Thanks for the reply. When you say "BookView bound to li.book, which should be fine with your current template structure". Do you mean one view bound to five seperate items? Is this acceptable? Doesn't backbone need to track these 5 items separately? Sorry for the broad questions - I'm just trying to get a grip of the concepts involved before jumping in.
–
calumbrodieJul 21 '11 at 13:33

It will bind a seperate view instance to each li! Evey time this happens also all events defined in the view will be bound to the view's elements, so if a view gets re-rendered all events should be defined (which is one big advantage of using backbone, no need to use something like jQuery's live in most situations)
–
Bernhard VallantJul 21 '11 at 14:22

Thanks for your help - more stupid questions in the near future no doubt
–
calumbrodieAug 5 '11 at 19:26

I was really trying to do the same thing as well and just found my way around it!

Was trying to build on a todo list example where I'd already have some todos on the page, want to bring them as models in my Todos collection and have them managed the same way it happens for elements that were added to a blank page.

The important part is on how to instantiate the collection. Basically:

you get your existing html elements through jQuery. If your model's view is based on a tagName: 'li', then this is the kind of tag you need to retrieve here.

You iterate through these tags to scrape the data that's in there that constitutes your models and create your models

You create a view for each model, passing it the model and the base element. This was the problem I had: I was creating the view and only then trying to add it later through my_view.el = xxx. This doesn't work.

You add your model to the collection

Note: the collection is usually tied to a view later so that using collection.add will update the view as well. Since initialize is called in the constructor, the collection has not been bound yet and you won't duplicate elements in your HTML by adding them here.

// this is the important part for initializing from html!
khepin.Todos = Backbone.Collection.extend({
model: khepin.Todo,
// In this function we populate the list with existing html elements
initialize: function() {
_.each(
// get all the <li></li> todo items (the base for the todo view)
// and for each of them:
$('.todo'),
function(a){
// Create the model
var todo = new khepin.Todo();
// Find the todo's text
var task = $(a).find('span')[0];
task = $(task).text();
// set the model correctly
todo.set({
task: task
});
// create the todo view
var todoView = new khepin.TodoView({
model: todo,
el: a // the el has to be set here. I first tried calling new TodoView and setting the 'el' afterwards
// and the view wasn't managed properly. We set the "el' to be the <li></li> we got from jQuery
});
// Add this new model to the collection
this.add(todo);
},
this
);
}
})