Backbone, Marionette: Collection view with different ChildViews used to display chessboard

This post is a part of Get Noticed! 2017 contest by Maciej Aniserowicz

CollectionView is quite interesting thing in Marionette, especially if you find that its ChildView can be set at runtime for every element of collection —which makes it perfectly suitable to display a simple chessboard. All changes you can find in commits summaries: White and black rows has been extracted to separated modules and Simple chessboard rendering has been added.

Like mine :), but without pawns, at least for now. Photo credits: Recal Media.

Solution to display a chessboard

Today’s post is a note rather that a real post, so to the point:

Chessboard as 8 x 8 matrix

So, it’s the same as collection with 8 elements, where every element is collection with 8 elements.

First collection

First collection is a list, where odd elements (count from 1) begin with white square, and even elements begin with black square. So, you can calculate simple model for this collection:

_getRows: function () {
const RowModel = Backbone.Model.extend({
initialize ({index}) {
this.odd = !!(index % 2);
this.even = !(this.odd);
this.index = index;
},
});
const Rows = Backbone.Collection.extend({
model: RowModel,
});
const rows = new Rows();
for (let index = 0; index < 8; index++) {
rows.add(new RowModel({
index: (index + 1),
}));
}
return rows;
}

And use it on ChessboardView:

this.showChildView('chessboard', new ChessboardView({
collection: this._getRows(),
}))

ChildView is not specified, because it will be calculated at runtime, to decide whether display row starting with white square (WhiteRowView) or black square (BlackRowView):

childView: function (item) {
if (item.odd) {
return WhiteRowView;
}
if (item.even) {
return BlackRowView;
}
},

(Read more on Marionette CollectionView docs).

But how they differ? Only notable difference is collection which they display, (cause they are CollectionViews, too):

collection: new Backbone.Collection([
{type: 'white'},
{type: 'black'},
{type: 'white'},
{type: 'black'},
{type: 'white'},
{type: 'black'},
{type: 'white'},
{type: 'black'},
])

It’s nice that model can be provided as plain JavaScript object — no need to create even temporary model. They both use SquareView to display square, which based on “model” adds classes to its own $el:

return Mn.View.extend({
template: _.template(``),
tagName: "p",
onRender: function () {
this.$el.css("display", "inline-block");
this.$el.addClass(`field field-${this.model.get("type")}`);
},
});

And that’s it!

Conclusion

Forgive me short post, I promise to shape up!