5

Trying to have a data field in a Handlebars template update after the model that is assigned to the Marionette CompositeView is fetched, but the HTML in the page is not getting updated.

My code looks like this:

Model:

B.Page.Model = Backbone.Model.extend({
    url: function () {
        return 'my/resource/';
    },
});


View:

B.Page.CompositeView = Backbone.Marionette.CompositeView.extend({
    template: Handlebars.compile(templates.find('#my-template').html()),

    initialize: function(options) {
        _.bindAll(this);
        this.model.fetch();
    },
)};


Template:

<script id="my-template" type="text/x-handlebars-template">
    Date: <span id="my-data-field">{{data}}</span>
</script>

I have checked the resource and it does return proper JSON with the data field set. Also, the model is getting passed in to the view.

I suspect that this is due to the render function not getting called after the data is retrieved; however, I would like to get feedback on how it should be done.

What is a good way to do this?

Thanks!

EDIT: This CompositeView does have a Collection that is associated with it (which renders just fine when I trigger the appropriate event). I purposefully left out that part of the code to avoid muddying up the problem.

Juan Carlos Coto
  • 11,900
  • 22
  • 62
  • 102

2 Answers2

3

Your are right, since a CompositeView extends from CollectionView, it only re-renders on collection events by default. To make it re-render on changes on your model, you could do something like this in your CompositeView:

initialize: function(){
    this.listenTo(this.model, "change", this.render);
}
zero-divisor
  • 560
  • 3
  • 19
  • Thanks. The actual syntax I used is `this.model.on('change', this.render)`, but it is clear that it is the same concept. – Juan Carlos Coto Dec 10 '13 at 00:59
  • Yes, it's the same concept, but there are slight differences: See [here](http://stackoverflow.com/questions/14041042/backbone-0-9-9-difference-between-listento-and-on) for example. – zero-divisor Dec 10 '13 at 06:15
1

All Marionette views have a modelEvents object that is bound to the passed in model. So you could clean the accepted answer up slightly by doing:

template: Handlebars.compile(templates.find('#my-template').html()),

modelEvents: {
    'change': 'render'
}

rather than binding manually in initialize.

Evan Hobbs
  • 3,552
  • 5
  • 30
  • 42