Tino
Tino

Reputation: 3368

Backbone View: Wait until collection fetched

I would like to know how to tell backbone to wait until my collection has fetched a model and then render the underscore bit.

In the console returns an error from the underscore template that a field is missing. When I console.log(this.collection.toJSON()) it doesn't show any data. So I assume, that the view is rendered before the data was fetched. How do I tell the view to wait until it is fetched?

/////// View////////

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/mitarbeiter',
  'text!/aquilamus/templates/mitarbeiter/mitarbeiter.html'
], function($, _, Backbone, MitarbeiterCollection, MitarbeiterTemplate){



 var MitarbeiterListView = Backbone.View.extend({
    el: $("#container"),
    initialize: function(){
      this.collection = new MitarbeiterCollection;
      this.collection.fetch();
      var newtemplate = MitarbeiterTemplate;
      this.template = _.template($(newtemplate).html());
    },
    render: function(){
      var renderedContent = this.template(this.collection.toJSON());

      $(this.el).html(renderedContent);
      return this;
    }


  });
  // Our module now returns our view
  return MitarbeiterListView;
});

Upvotes: 3

Views: 8566

Answers (5)

xwhyz
xwhyz

Reputation: 1514

This worked the best for me:

var ArtistListView = Backbone.View.extend({
        el: '.left',
        initialize:function(){
            this.render();
        },
        render: function () {
            var source = $('#my-list-template').html();
            var template = Handlebars.compile(source);
            var collection = new MyCollection;
            collection.fetch({async:false});
            var html = template(collection.toJSON());
            $(this.el).html(html);
       });

Upvotes: 2

Marius Kjeldahl
Marius Kjeldahl

Reputation: 6824

fetch also allow you to pass a success handler function which will be called when fetch succeeds, i.e.:

  this.collection.fetch({success: this.render});

Upvotes: 1

Paul Hoenecke
Paul Hoenecke

Reputation: 5060

Using reset like others suggested works, but here is an alternative.

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/mitarbeiter',
  'text!/aquilamus/templates/mitarbeiter/mitarbeiter.html'
], function($, _, Backbone, MitarbeiterCollection, MitarbeiterTemplate){

 var MitarbeiterListView = Backbone.View.extend({
    el: $("#container"),
    initialize: function(){
      this.collection = new MitarbeiterCollection;

      var newtemplate = MitarbeiterTemplate;
      this.template = _.template($(newtemplate).html());
    },
    render: function(){
      var self = this;

      // show some loading message
      this.$el.html('Loading');

      // fetch, when that is done, replace 'Loading' with content
      this.collection.fetch().done(function(){
          var renderedContent = self.template(self.collection.toJSON());
          self.$el.html(renderedContent);
      });
      return this;
    }

  });
  // Our module now returns our view
  return MitarbeiterListView;
});

Yet another alternative is to do something very similar to this, except use the success callback function which you can put in the fetch options.

Upvotes: 11

Venkat Kotra
Venkat Kotra

Reputation: 10753

Collection fetch triggers an event 'reset' when fetch is complete. You can utilise that fetch event

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

Upvotes: 1

HungryCoder
HungryCoder

Reputation: 7616

I do not know any way to say it to wait but I know you can tell backbone to (re)render when your collection is fetched.

initialize: function(){
      this.collection = new MitarbeiterCollection;
      this.collection.fetch();
      var newtemplate = MitarbeiterTemplate;
      this.template = _.template($(newtemplate).html());
      this.collection.on('reset', this.render, this);
    },

The last line listens to your collection's reset event. When it is triggered, it will call the render method.

Upvotes: 1

Related Questions