Search code examples
javascriptbackbone.js

Backbone Create Collection then View - Async?


I have the following backbone code:

var BookListView = Backbone.View.extend({
    initialize: function(){
        var self = this;
        this.listenTo(this.model, 'change add remove update', this.render);
        //this.listenTo(this.model, 'reset', this.render);
    //this.model.bind('reset', this.render, this);
        console.log('BookListView created');
    },
    model: BookCollection,

    render: function(){
        this.$el.html('');
        var self = this;
        for(var i = 0 ; i < this.model.length ; ++i){
            var singleBookView = new BookView({model: this.model.at(i)});
            this.$el.append(singleBookView.$el);
            singleBookView.render();
        }
        return this;
    }
});

console.log('C loaded');
var bc = new BookCollection();

// Run after the bc is created
setTimeout(function(){
    blv = new BookListView({model: bc, el: $('#book-el')});
    bc.fetch();
} , 400);

This code works and renders my book list properly after a 400 ms delay.

however, if I remove the setTimeout and run the 2 lines of code right after I create my BookCollection, it does not render properly. This does not work:

console.log('C loaded');
var bc = new BookCollection();

blv = new BookListView({model: bc, el: $('#book-el')});
bc.fetch();

Why can't I use bc right after I create it? Why do I have to delay, and how can I get around that?


Solution

  • This could be happening because it is running before the DOM is ready, so it's possible that #book-el has not yet loaded.

    Here is how I usually instantiate Backbone classes:

    function init() {
        var bc = new BookCollection();
        blv = new BookListView({model: bc, el: $('#book-el')});
        bc.fetch();
    }
    
    // When the document is ready, call the init function
    $(function() {
        init();
    });