Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js: Fetch a collection of models and render them

I am learning JavaScript MVC application development using Backbone.js, and having issues rendering model collection in the view. Here's what I want to do:

  • After the page finishes loading, retrieves data from the server as model collection

  • Render them in the view

That's all I want to do and here is what I have so far:

$(function(){

    "use strict";

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

    var PostCollection = Backbone.Collection.extend({
        model: PostModel,
        url: 'post_action.php'
    });

    var PostView = Backbone.View.extend({
        el: "#posts-editor",        

        initialize: function(){
            this.template = _.template($("#ptpl").html());
            this.collection.fetch({data:{fetch:true, type:"post", page:1}});
            this.collection.bind('reset', this.render, this);
        },

        render: function(){
            var renderedContent = this.collection.toJSON();
            console.log(renderedContent);
            $(this.el).html(renderedContent);
            return this;
        }
    });

    var postList = new PostCollection();
    postList.reset();
    var postView = new PostView({
        collection: postList
    });

});

Problem

As far as I know, Chrome is logging the response from the server and it's in JSON format like I want it. But it does not render in my view. There are no apparent errors in the console.

The server has a handler that accepts GET parameters and echos some JSON: http://localhost/blog/post_action.php?fetch=true&type=post&page=1

[
   {
      "username":"admin",
      "id":"2",
      "title":"Second",
      "commentable":"0",
      "body":"This is the second post."
   },
   {
      "username":"admin",
      "id":"1",
      "title":"Welcome!",
      "commentable":"1",
      "body":"Hello there! welcome to my blog."
   }
]
like image 959
hyde Avatar asked Jul 11 '13 22:07

hyde


People also ask

Is BackboneJS still relevant?

Backbone. Backbone has been around for a long time, but it's still under steady and regular development. It's a good choice if you want a flexible JavaScript framework with a simple model for representing data and getting it into views.

What is collections in BackboneJS?

Advertisements. Collections are ordered sets of Models. We just need to extend the backbone's collection class to create our own collection. Any event that is triggered on a model in a collection will also be triggered on the collection directly.

What is BackboneJS used for?

BackboneJS is a lightweight JavaScript library that allows to develop and structure the client side applications that run in a web browser. It offers MVC framework which abstracts data into models, DOM into views and bind these two using events.


2 Answers

There are 2 potential problems with your code.

  1. The event listener callback should be registered before calling the collection.fetch(). Otherwise, you might miss the first reset event as it might be triggered before the listener is registered.

  2. The reset event is not enough to ensure that the view will re-render every time the collection gets updated.

Also, note that it is a good practice to use the object.listenTo() form to bind events as it will ensure proper unregistration when the view is closed. Otherwise, you may end up with what is known as Backbone zombies. Here is a solution.

this.listenTo( this.collection, 'reset add change remove', this.render, this );
this.collection.fetch({ data: { fetch:true, type:"post", page:1 } });

Note how you can register multiple events from the same object by separating them with whitespace.

like image 124
mor Avatar answered Sep 19 '22 08:09

mor


change

this.collection.bind('reset', this.render, this);

to

this.collection.bind('sync', this.render, this);

The problem is you perform reset only once, in the beginning. And at that time you don't have anything to render. The next time, when you fetch your collection, reset event doesn't fire, because you fetch collection without option {reset: true}.

like image 37
Artem Volkhin Avatar answered Sep 21 '22 08:09

Artem Volkhin