Tuesday, December 9, 2014

Marionette: Simple Text Views For Regions

Layout views in Marionette are great, and I think they should be used wherever possible. Any given page should be divided into regions — it's just a good habit to have. There are times when regions are a pain, however, because all you want to render is some simple text. Most of the time, regions will show more complex views that do a fair amount of work. They have templates, they have a model or collection as context, and so on. The challenge is being able to swap out something complex with something simple.

The approach I've come up with involves defining a generic text view. It's still a view, despite the fact we're only using it to display some simple text, but it's lightweight nonetheless. With something like this in place, I'm less discouraged by regions when I want to do something as pedestrian as render some text in a DOM node. And I get to keep my Marionette patterns in-tact.

Let's create a simple application and layout view so we have some regions to work with:

var layout = new Marionette.LayoutView({
    template: _.template('<p></p><p></p>'),
    regions: { first: 'p:first', last: 'p:last' }
});

var application = new Marionette.Application({
    regions: { main: 'body' }
});

application.main.show(layout);

Now there's two regions that are empty <p/> elements — first and last. Let's now take a look at how we would define a generic text view that will take some text we want displayed, and render it:

var TextView = Marionette.ItemView.extend({
    initialize: function() {
        this.template = _.wrap(
            this.getOption('text'),
            _.identity
        );
    }
});

layout.first.show(new TextView({ text: 'hello' }));
layout.last.show(new TextView({ text: 'world' }));

Now we have a TextView view that accepts a text option, and this is what's rendered. The idea is that instead of passing in a template option, in the view constructor, we give it our own template function. I'm using some Lo-Dash tools here to help construct it. Essentially, we're wrapping the supplied text option in the identity() function — which just returns whatever value is passed to it. And that's it, our two paragraph regions are populated with their respective text — "hello" and "world".