Collection fetch does not render on "add" event #2078

Closed
omsoft opened this Issue Jan 6, 2013 · 4 comments

Comments

Projects
None yet
3 participants

omsoft commented Jan 6, 2013

I've set up this AppView that triggers the overall Backbone's application!
I want to fetch my collection and dynamically add items when the "add" event is thrown!

var AppView = Backbone.View.extend({
    el: $('#pics'),

    initialize: function () {

        // Fetch contents
        this.collection = new PLibrary;
        this.collection.on("add", this.renderMessage, this);

        $.ajaxSetup({async: false});
        this.collection.fetch({update: true});  // fires an "add" event for every new model
        $.ajaxSetup({async: true});

        _.bindAll(this, 'render');
    },

    renderMessage: function(p){
        var mV = new PRow({model: p});
        this.$el.append(mV.render().el);
    }

});

The code above sends the Ajax request to the server, but nothing gets displayed.
Instead... If I make use of render() like this... the application works.

var AppView = Backbone.View.extend({
    el: $('#pics'),

    initialize: function () {

        // Fetch contents
        this.collection = new PLibrary;
        this.collection.on("add", this.renderMessage, this);

        $.ajaxSetup({async: false});
        this.collection.fetch();
        $.ajaxSetup({async: true});

        _.bindAll(this, 'render');
        this.render();
    },

    renderMessage: function(p){
        var mV = new PRow({model: p});
        this.$el.append(mV.render().el);
    },

    render: function() {
        var self = this;
        _.each(this.collection.models, function (item) {
            self.renderMessage(item);
        }, this);
    }

});

It seems that the "add" event doesn't get thrown!
Help me please

Contributor

yuku-t commented Jan 6, 2013

Collection#fetch uses Collection#reset internally by default and it triggers "reset" event on the collection instance but doesn't tigger "add" event.
If {update: true} is given to Collection#fetch then Collection#update is executed and it may trigger "add", "remove" and "change" events.
So, there are two solutions.

  1. Set render as callback of collection's "reset" event
  2. Give {update: true} to Collection#fetch

I like 1. Because it is easy to implement and update is a little heavier than reset.

omsoft commented Jan 6, 2013

If you take a closer look at my first code snippet, you'll see the call fetch({update: true}).
My question is, infact, why it doesn't work?

Contributor

yuku-t commented Jan 6, 2013

Oh, excuse me. The first code looks correct. ummm
Could you show me the console string of following code?

console.log(Backbone.VERSION);
var collection = new PLibrary();
collection.on('all', function () { console.log(arguments); }); 
collection.fetch({update: true, async: false});
collection.fetch();

Expect:

0.9.9
['add', ModelObject, CollectionObject, OptionObject]
['add', ModelObject, CollectionObject, OptionObject]
...
['reset', CollectionObject, OptionObject]

Model#updatewas added at 0.9.9.

omsoft commented Jan 12, 2013

Thank you very much! I was working with an old version of Backbone. Updated to 0.9.9 and now it works as expected!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment