Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a collection using fetch with backbone

Based on the official documentation, when I do something like this:

collection.fetch({update: true, remove: false})

I get an "add" event for every new model, and a "change" event for every changed existing model, without removing anything.

Why if I'm calling an static source of data (the url of the collection always return the same json) an add event is called for each item received?

Here some code (I'm not rendering anything, I'm just debugging):

<!doctype html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <a href="#refresh">Refresh</a>
    <script src="js/jquery-1.8.3.min.js"></script>
    <script src="js/underscore-min.js"></script>
    <script src="js/backbone-min.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>

Heres the JS

(function($){
    //Twitter Model
    ModelsTwitt = Backbone.Model.extend({});
    //Twitter Collection
    CollectionsTwitts = Backbone.Collection.extend({
        model:ModelsTwitt,
        initialize:function(){
            console.log('Twitter App Started');
        },
        url:'data/195.json'
    });
    //Twitts View
    ViewsTwitts = Backbone.View.extend({
        el:$('#twitter-list'),
        initialize:function(){
            _.bindAll(this, 'render');
            this.collection.bind('reset',this.render);
            this.collection.bind('add',this.add);
        },
        render:function(){
            console.log("This is the collection",this.collection);
        },
        add:function(model){
            console.log("add event called",model);  
        }
    });
    //Twitter Router
    Router = Backbone.Router.extend({
        routes:{
            '':'defaultRoute',//Default list twitts route
            'refresh':'refreshView'
        },
        defaultRoute:function(){
            this.twitts = new CollectionsTwitts();
            new ViewsTwitts({collection:this.twitts});
            this.twitts.fetch();
        },
        refreshView:function(){
            this.twitts.fetch({update:true,remove:false});
        }
    });
    var appRouter = new Router();
    Backbone.history.start();
})(jQuery);

Basically, I fetch the collection using the defaultroute, it is fetched properly with all the models and attributes.

And when I click on the refresh link, I call refreshView, which basically tries to update the collection with new models. What I don't understand is why if the response is the same, all the models of the collection are detected as new, triggering an add?

Heres a functional link: open the console and you will see how the add events are called when you click on refresh even when the collection is the same.

Thanks for your help.

like image 355
DiegoVargasg Avatar asked Feb 12 '13 02:02

DiegoVargasg


1 Answers

My guess would be that your models don't have an idAttribute (doc). The default key Backbone looks for is id and your JSON entries don't have one so it can't tell which models are already there.

Try changing your model to this (or another key if this one isn't unique):

ModelsTwitt = Backbone.Model.extend({
  idAttribute: 'id_event'
});
like image 100
mtth Avatar answered Oct 10 '22 04:10

mtth