0

I've noticed Marionette is very un-opinionated as far things go for the freedom they give you to choose a method to render data. It seems like there are a lot of ways to initially render a template with custom data

Returning a template with data:

template: function () {
    var myTemplate = $('.someTemplate')
    return _.template(myTemplate.html())({some: data});
}

Very similarly:

    render: function () { 
        var template = this.getTemplate();
        var html = Marionette.Renderer.render(template, {
            model: this.model.toJSON(),
            customData: this.customData
        });

        this.$el.html(html);
    }

Serialize data:

serializeData : function () {
    var customData = {some: 'data'};
    var model = this.model.toJSON()
    return _.extend(customData, model);
}

I've seen a lot of people in different code use variations of the first and the second. I personally prefer using serializeData but am curious: is there an advantage or use case where it would be appropriate to use the first two methods instead of serializeData?

Yahkob
  • 104
  • 7

2 Answers2

2

The first case is not efficient - you are recompiling the template every time you want to render.

Anyway, your use case is exactly why Marionette has templateHelpers. Its the most concise way to provide extra data to the template while also passing serialized model.

So you would write:

templateHelpers : function () { return {some: 'data'}; }

Or if its just static stuff:

templateHelpers: {some: 'data'}

More examples on how to use it here.

Paulius
  • 363
  • 1
  • 7
  • What are the advantages of using templateHelpers vs serializeData? – Yahkob Sep 30 '15 at 02:29
  • serializeData is internal Marionette method which gives different output for collection and model. You can see its implementation here: https://github.com/marionettejs/backbone.marionette/blob/master/src/item-view.js#L22 Thats why I like to leave it alone. Its just the matter of convention. – Paulius Sep 30 '15 at 02:56
  • Agreed, `templateHelpers` should be the standard approach. @Yahkob, I wrote a bit about the difference in [this answer](http://stackoverflow.com/a/32232761/2395796). – Kevin Christopher Henry Sep 30 '15 at 03:25
  • @KevinChristopherHenry @Paulius I actually found today that there are some cases you would need to use `serializeData` for instance if you want to render items from `this.options` in your template you would need to specify those in a `serializeData` function, `this` is not available in `templateHelpers` – Yahkob Oct 02 '15 at 05:44
  • @Yahkob: `this` certainly is available in `templateHelpers`. From the [documentation](http://marionettejs.com/docs/marionette.view.html#object-or-function-as-templatehelpers): "If you specify a function, the function will be invoked with the current view instance as the context of the function." – Kevin Christopher Henry Oct 02 '15 at 07:00
  • @KevinChristopherHenry Yeah I read this part but I think in some conditions it is easier to just use serializeData instead of binding templateHelpers. I guess I could have said in some conditions this MAY not be available without binding which at that point I think it is intuitive to just use serialize data :) – Yahkob Oct 02 '15 at 21:13
1

I think it's all about exploring natural behaviour of these things. Backbone View render is empty function by default. Marionette ItemView render extends Backbone's with this code.

  1. It takes template by getTemplate method, by default it gives what is stored in template option. You can override getTemplate if you want to choose between several templates.
  2. Then it collects data needed to be rendered by runing serializeData and extending it with templateHelpers. First one by default returns your model or collection toJSON method result, there you can prepare your data some way on every render. Second one is for helpers that will be calculated (if they are functions) if needed in template.
  3. Template and data then go to Marionette.Renderer where just return template(data) by default happens. And then result can be attached to view's element.
antejan
  • 2,594
  • 12
  • 15