Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Backbone.Marionette from rendering a view if it's model hasn't been fetched?

In my backbone.Marionette application I have a Model that requires an Id attribute to construct it's url. I therefore create the model by passing it an Id, add it to a view and then fetch the model:

   model = new Model({_id:id})               
   view = new View({model:model})                               
   app.content.show(view)                                                    
   model.fetch()

I would expect the view to only start rendering once the model has been fetched, but Marionette renders the model immediately causing my template rendering to fail as the expected attributes don't exist. Any workarounds?

I'm trying to do something similar to the accepted answer here: Binding a Backbone Model to a Marionette ItemView - blocking .fetch()?

But while that works with backbone, as stated in the answer, Marionette automatically renders the view.

Also see: Backbone Marionette Displaying before fetch complete

like image 673
Rudolf Meijering Avatar asked Nov 26 '12 14:11

Rudolf Meijering


3 Answers

Both answers above work.
Here's yet another way which I prefer to use (feels more backboney).

Bind the view directly to the model
When the model is done being fetched, the function you specify will run. This can be done with models or collections.

var Model = Backbone.Model.extend({});
var model = new Model();
model.fetch();

var View = Marionette.ItemView.extend({
    model:model,
    initialize: function(){
        this.model.bind("sync", this.render, this);// this.render can be replaced
    }                                              // with your own function
});                               

app.region.show(new View);                                           

This also enables you to fetch whenever you want.

like image 142
Jupo Avatar answered Jan 02 '23 21:01

Jupo


If you truly want to prevent rendering until the model has been fetched you should reorder your calls like this:

model = new Model({_id:id});
view = new View({model:model});
model.fetch({success: function () {
  app.content.show(view);
});

Alternatively, you should think about rendering immediately and taking advantage of Marionette's blank state support.

like image 21
Andrew Hubbs Avatar answered Jan 02 '23 21:01

Andrew Hubbs


based on one of Derick Bailey's examples:

 model = new Model({_id:id})               
   var fetched = model.fetch();

  // wait for the model to be fetched
  $.when(fetched).then(function(){

     view = new View({model:model})                               
     app.content.show(view)     
  });
like image 45
danikoren Avatar answered Jan 02 '23 21:01

danikoren