-1

I have defined a Model and a Collection, and since I already have records in my database, I wish to show all those records on application on page load.

I tried using Backbone.sync, but I still see an empty collection in Chrome debugging mode.

My Backbone.js code:

http://jsfiddle.net/GhaPF/15/ (I had to remove some code there because of template dependencies).

$(document).ready(function() {

    var Item = Backbone.Model.extend({
        defaults: { "date": "",
                    "text": "default text"
                },
        initialize: function() {      // STEP 3
            var dateString = giveMeDate();
            this.set("date", dateString);
        },
        urlRoot : './items'
    });

    var ItemList = Backbone.Collection.extend({
        model: Item,
        url: './items/',
        initialize: function() {
            this.fetch();
        }
    });


   //************ VIEW ********************************
    var ItemListView1 = Backbone.View.extend({
        el: 'body',
        initialize: function(myitemList) {
            this.itemlist = myitemList;
            this.itemlist.bind('add', this.addOneItem, this);
            this.render();
        },
        addOneItem: function() {
            this.render();
        },
        render: function() {                // STEP 5       this is called because add() is bound to this.render (in initialization of this View)
            text = this.itemlist.toJSON();
            string = JSON.stringify(text);
            $("#view1").html('');
            $.tmpl("itemTemplate", text).appendTo("#view1");
            return this;
        },
        events: {
            "keypress #new-item":  "createOnEnter"    // STEP 1
        },
        createOnEnter: function(e) {
          if (e.keyCode != 13) return;
          if (!$("#new-item").val()) return;
          this.itemlist.create({"text": $("#new-item").val()});   // STEP 2
          $("#new-item").val('');
        }
    });


    $("#new-item").focus();
    var itemlist = new ItemList();
    Backbone.sync("read", itemlist);
    var myitemListView = new ItemListView1(itemlist);

Here is what I see in the collection after Backbone.sync:

d
_byCid: Object
_byId: Object
length: 0
models: Array[0]
__proto__: x
Timothée HENRY
  • 14,294
  • 21
  • 96
  • 136
  • Please try to remove as much code as possible until you come up with the minimal portion of code that reproduce the issue. This should be a required step to ask a question. – fguillen Sep 07 '12 at 13:06
  • the `url` you assign for the collection must point to an address that returns the collection's contents as JSON. Backbone will take care of the rest. Also you don't have to call `Bacbone.sync` every time you want to sync with the server. `collection.fetch()` is the correct way to do it. – jakee Sep 07 '12 at 13:07

1 Answers1

3
  1. You probably should not call sync directly, as that method may be overwritten with some other sync method (for supporting localStorage, IndexedDB, couchdb or whatever). Sync is more like a "storage driver".

  2. You should call fetch to populate your collections. So in your code, it should be something like this:

    itemlist.fetch({success: function (models) {
       console.log("got", models);
    });
    var myitemListView = new ItemListView1({collection: itemList});
    
  3. It's considered "poor style" to populate your collection with an async fetch right after a page load. You should typically populate it with code that is sent down together with the page, and only use fetch for subsequent updates to the collection.

In the code example above, if you insist on doing the async fetch, you may want to delay creating your view until you actually have the collection populated to avoid unecessary flashes when the list goes from empty to filled (the view is bound to the collection and will reset when the fetch completes).

Marius Kjeldahl
  • 6,830
  • 3
  • 33
  • 37