Reputation: 147
I'm using a composite view to display a table with Backbone Marionette, but having some trouble getting the wrapper part of the template to rerender when the data comes in after I do a fetch on my model. Here are my templates:
The composite view's template:
<thead>
<tr>
{{#each report.columns}}
<th>{{name}}</th>
{{/each}}
</tr>
</thead>
<tbody></tbody>
And the ItemView's template:
{{#each cols}} <td>{{value}}</td> {{/each}}
In my controller function, I'm creating the instance of the model, creating and showing the view, and doing a fetch to get my data into the model:
var tView = new tableCompositeView({collection: rowsCollection, model: configModel});
layoutView.tablecontent.show(tView);
rowsCollection.fetch();
configModel.fetch();
The collection items come in fine, the view is updated when the fetch is successful. The wrapper bit in the composite view's template never gets updated when the configModel.fetch() finishes, though.
In the docs, it says you can use .renderModel() to re render only the parts of the view that deal with the model. When I do this:
configModel.fetch().success(function(){ tView.renderModel(); });
Nothing changes. But when I use .render():
configModel.fetch().success(function(){ tView.render(); });
It works fine and gets updated. This could work for now, but it's rerendering my entire table which could be kind of a performance issue
Upvotes: 2
Views: 2067
Reputation: 3684
I think the docs are misleading in this case. renderModel returns the html for the rendered view. It does not touch the $el.
renderModel: function(){
var data = {};
data = this.serializeData();
data = this.mixinTemplateHelpers(data);
var template = this.getTemplate();
return Marionette.Renderer.render(template, data);
},
If you are interested in rendering things in the proper order you don't have to worry about explicitly calling render. Instead you can defer showing the view until your models fetch is complete. Then simply calling App.region.show(view); will put everything in place for you.
Here is a fiddle to illustrate: http://jsfiddle.net/nEArw/12/
var metaPromise = Mod.metaModel.fetch({dataType: "jsonp"});
var tagsPromise = Mod.tagsCollection.fetch({dataType: "jsonp"});
metaPromise.done(function(data) {
App.region.show(Mod.compositeView);
});
tagsPromise.done(function(data) {
console.log("tags fetched!");
});
If model updates occur after you show the view and you want to avoid re-rendering the whole composite you can use modelEvents in your compositeView to update individual elements.
modelEvents: {
"change:name": "nameChanged"
},
Or if you want to go a bit further down the rabbit hole you can use a model binding plugin. https://github.com/theironcook/Backbone.ModelBinder
Upvotes: 6