backbone.js

Backbone "reset" collection trigger not firing


I'm using backbone.js to get a collection from the REST server. Fetch triggers fine and fills the collection with the data. However, the "reset" trigger is never fired and so addAll() is never called. Calling addAll() manually works fine - but why isn't "reset" firing as it should when fetch() is called on the collection?

Here is the code:

Model

define(['backbone-tastypie'], function(Backbone) {
    var Machine = Backbone.Model.extend({
        url: function(){
            return this.get('resource_uri') || this.collection.url;
        }
    });

    return Machine;
});

Collection

define(['backbone-tastypie','models/machine'], function(Backbone, Machine) {
    var Machines = Backbone.Collection.extend({

        model: Machine,
        url: '/api/rest/machine/',
        parse: function(data){
            return data.objects;
        }
    });

    return Machines;
});

Model View

define(['underscore','backbone-tastypie'], function(_, Backbone) {
    var MachineTableEntryView = Backbone.View.extend({
        tagName: 'tr',
        template: _.template($('#machine-row-template').html()),

        render: function(){
            $(this.el).html(this.template(this.model.toJSON()));
            console.log('lol');
            return this;
        }   
    }); 

    return MachineTableEntryView;
});

Main View

define(['underscore','backbone-tastypie','collections/machines','views/machine_table_entry'], function(_, Backbone, Machines, MachineTableEntryView) {
    var MachineTableView = Backbone.View.extend({
        el: $('#app'),

        initialize: function(){
            _.bindAll(this, 'addOne', 'addAll');

            Machines.bind('reset', this.addAll);

            this.machines = new Machines();
            this.machines.fetch();
        },

        addAll: function(){
            this.machines.each(this.addOne);
        },

        addOne: function(machine){  
            var view = new MachineTableEntryView({model:machine});
            this.$('#machines').append(view.render().el);
        },
    });

    return MachineTableView;
});

Solution

  • You need to bind the event listener to the instance of the collection you create, not the Collection constructor:

    define(['underscore','backbone-tastypie','collections/machines','views/machine_table_entry'], function(_, Backbone, Machines, MachineTableEntryView) {
    var MachineTableView = Backbone.View.extend({
        el: $('#app'),
    
        initialize: function(){
            _.bindAll(this, 'addOne', 'addAll');
    
            this.machines = new Machines();
            this.machines.bind('reset', this.addAll);
            this.machines.fetch();
        },
    
        addAll: function(){
            this.machines.each(this.addOne);
        },
    
        addOne: function(machine){  
            var view = new MachineTableEntryView({model:machine});
            this.$('#machines').append(view.render().el);
        },
    });
    
    return MachineTableView;