Mr The Falcon
Mr The Falcon

Reputation: 91

How do I bootstrap a collection in Backbone.js using Javascript only

Context: I am building an application that needs several large collections of reference data to operation. I am limited to HTML and Javascript only (including JSON).

Question: How do I bootstrap a collection in Backbone.js where the collection objects are in JSON format on the server and I'm using Javascript only?

This is what I know already:

This is what I've come up with so far:

ItemList = Backbone.Collection.extend({
  model: Item,
  url: 'http://localhost:8080/json/items.json'
});
var itemList = new ItemList;
itemList.fetch();
itemList.on('reset', function () { dqApp.trigger('itemList:reset'); });

'dqApp' is my application object. I can display a spinner, and update a loading status while collections are being populated by sending alerts to the application object.

Upvotes: 8

Views: 4273

Answers (3)

Gui Ambros
Gui Ambros

Reputation: 1065

One possible solution is to make your view dependent on the status of fetch, so it doesn't get instantiated until your model/collection has finished loading.

Just keep in mind this is a Backbone anti-pattern. Making the view dependent on your collection/model will likely cause UI delays. That's why the recommended method is to bootstrap your data by inlining the json directly in your page.

But this doesn't solve your situation, where you need to bootstrap data on a server-less situation. It's easy to embed json data in your page dynamically with a few lines of Ruby/PHP/etc, but if you're working client-side only, making the view dependent on the model is the way to go.

If you're loading the collection using fetch(), you can use something like:

var Model = Backbone.Model.extend({});

var Collection = Backbone.Collection.extend({
    model: MyModel,
    url: 'http://localhost:8080/json/items.json'
});

var View = Backbone.View.extend({
    //code
});

var myCollection = new Collection();

myCollection.fetch({
    success: function () { 
        console.log('Model finished loading'); }
        myView = new View();
  });

My preferred way is using ajax (e.g., .getJSON, .ajax) and saving the returned jqXHR object (or XMLHTTPRequest, if you're not using jQuery) to a property in your model. This way you have more granular control, and can use the deferred object response to check for the status of the call before creating your view.

var Model = Backbone.Model.extend({});

var Collection = Backbone.Collection.extend({
    model: Model,
    status: {},
    initialize: function () {
        var _thisCollection = this;
        this.status = $.getJSON("mydata.json", function (data) {
            $.each(data, function(key) {
                var m = new Model ( {
                        "name": data[key].name,
                        "value": data[key].value,
                    } );
                _thisCollection.add(m);
            });
        });
    }
});

var View = Backbone.View.extend({
    console.log( "Creating view...");
    //code
});

var myCollection = new Collection();
var myView = {};
myCollection.status
    .done(function(){
        console.log("Collection successfully loaded. Creating the view");
        myView = new View();
    })
    .fail(function(){
        console.log("Error bootstrapping model");
    });

Upvotes: 0

Snowball
Snowball

Reputation: 11686

The fetch function accepts an options parameter, which can have a success callback:

var itemList = new ItemList;
itemList.fetch({success: function () {
    dqApp.trigger('itemList:reset');
}});

Upvotes: 1

Justin wong
Justin wong

Reputation: 638

this may be help you : http://ricostacruz.com/backbone-patterns/#bootstrapping_data

Upvotes: 5

Related Questions