I'm having problems refreshing collection or more precisely collection view after updating all models on the server. Here's my scenario:
I have a collection of questions fetched from the server. Each question has a position attribute so I can manipulate the order in the list and save it back to the server with appropriate order.
I have a view for each single list item and a view with a more global scope that generates each list items and updates the collection. Basically I was using an example from O'Reilly book "Javascript Web Applications" which resembles a lot to the famous Todo annotated tutorial found here: http://documentcloud.github.com/backbone/docs/todos.html So the structure is almost identical apart from a few custom models. Everythings works fine.
However, I'm having problems updating the collection with I reorder items in the I've a method in my global view which fires evert time I drag list items in the list. Btw it works well and updates the order of the items on the server, but I also want to be able to update the digit in from of each item in the list.
window.QuestionView = Backbone.View.extend({ el: $("#content"), events : { 'sortupdate ol#questions': 'sortStuff' }, initialize: function(collection) { this.collection = new QuestionsList; _.bindAll(this, 'addOne', 'addAll', 'render', 'addNewItem', 'addItem'); this.collection.bind('add', this.addNewItem); this.collection.bind('all', this.render); this.collection.bind('reset', this.addAll); this.collection.fetch({ data: { quiz_id: $qid }, processData:true }); }, render: function() {}, sortStuff: function() { $this = this; $.ajax({ url: "/hq/reorder/", type: "POST", data: $("#questions").sortable("serialize")+"&id="+$qid, dataType: 'json', success: function(data) { } }); }, addItem: function() { this.collection.add({title: 'New title goes here'}); return false; }, addNewItem: function(question) { var view = new ItemView({model: question, parent: this}); var element = view.render().el; this.$("#questions").prepend(element); $that = this; $(view.render().el).addClass('new'); }, addOne: function(question) { var view = new ItemView({model: question, parent: this}); this.$("#questions").prepend(view.render().el); }, addAll: function() { this.collection.each(this.addOne); return false; }});
Also my success: function(data) returns the new order as a list (or JSON object) from the server. maybe I can reuse this order to set each model with a new value without making unnecessary fetch() call on the server each time the order is changed?
EDIT:
I finally managed to get it to work with a reset, clearing the view and re-fetching a new collection. Perhaps it isn't the best way to do it since there's additional call to the server with a fetch()..
sortStuff: function() {
$this = this;
$.ajax({
url: "/hq/reorder/",
type: "POST",
data: $("#questions").sortable("serialize")+"&id="+$qid,
dataType: 'json',
success: function(data) {
$this.rerender();
}
});
},
rerender: function() {
this.collection.fetch({
data: { quiz_id: $qid },
processData:true
});
$("#questions").html("");
this.collection.reset();
this.addAll();
},