Backbone, Marionette: Collection view with different ChildViews used to display chessboard
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.
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 CollectionView
s, 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!