Tuesday, October 30, 2012

Enhancing Backbone.js with Occamsrazor.js

WARNING. This article is an early experiment ! This way to enhance backbone.js is much better!

In this post I want to share a little experiment I made with Backbone.js and Occamsrazor.js. But before that I want to explain briefly what Backbone.js and Occamsrazor.js are.

Backbone.js

Backbone.js is a Javascript library useful to build structured UI. It's main role is to coordinate one or more models with their visual representations (views). It also manage the data exchange with the backend. (It is designed to be used in the frontend).
The core of Backbone.js is made of three powerful types of object:
  • models
  • collections
  • views
The model is an atomic unit of data. The collection is a group of objects that share the same model. The view keeps updated the visual representation of a model or a collection. The coordination between each these object is decoupled using events (observer pattern).

The web is plenty of Backbone.js documentation. For example:

Occamsrazor.js

Occamsrazor.js is a plugin system I wrote some time ago. I wrote about that here and here.

Why use these libraries together ?

With Occamsrazor.js a collection can contain objects of different types. To say the truth, in my experiment there is only one type of model but it can behave differently based on its fields.
For example we can decide which view is more appropriate.

The results

The demo is here (it is quite funny, I put in box2d and other libraries).
The "CanvasPlayView" view is responsible to draw all of the bodies on a canvas. In the render method we found this:

        models.bodies.each(function (element, index){
            var pos, x, y, angle;
            pos = positions[element.id];
            if (! pos){
                return;
            }
            x = pos.x;
            y = pos.y;
            angle = pos.angle;

            canvasLayer.ctx.save();
            canvasLayer.ctx.translate(x * canvasLayer.scale, y * canvasLayer.scale);
            canvasLayer.ctx.rotate(angle);

            plugins.drawer(element).render(canvasLayer);

            canvasLayer.ctx.restore();

        });

"Plugin.drawer" is not a regular function. It's a plugin!
This plugin is added in the rect module (the module containing all the plugins for the rectangular bodies) :

plugins.drawer.add(function (element){
    var GenericModelView = Backbone.View.extend({
        render: function(canvasLayer){
            var m = this.model,
                scale = canvasLayer.scale,
                w = m.get('width') * scale,
                h = m.get('height') * scale;

            canvasLayer.ctx.fillStyle = m.get('color');
            canvasLayer.ctx.fillRect(
                -(w / 2),
                -(h / 2),
                w,
                h
            );

            return this;
        }
    });
    return new GenericModelView({model:element });

}, plugins.validators.isBox);

More info on how Occamsrazor.js works are here.

I consider this experiment a step in the right direction.
Soon I'll try to make further steps.