Last Updated: February 25, 2016
·
722
· crusoexia

A simple Backbone muck-up subview implementation

Backbone is a really elegant, light weight and flexible lib, and because of it's flexibility, it leaves a great gap to you to make it works as a "framework". Here is an example of how to write a Backbone muck-up subview which can let you place your subview in the html instead of combine them in the JavaScript.

Dependencies

To implement the subview in the muck-up, we need below libs to work with Backbone together:

Handlebars

Underscorejs

Requirejs

Jquery

Usage

Let's see how it works first. Put below snippet in your html and leave the rest work to The Handlebars

{{render model id="myRenderer" class="myClass" renderer="path.of.renderer" otherAttributes}}

or

{{render renderer="path/of/renderer" otherAttributes}}

Implement

// A subview holder of the current stage. Can be used to
// retrieve the views, or tear down when leave the stage.
var stage = [];

(function() {

    Handlebars.registerHelper('render', function(context, options) {
        var attributeHash = (options && options.hash) || context.hash, 
            tag = attributeHash.tag || "div",
            viewModel = options ? context : null,
            token = _.uniqueId();

        if (attributeHash.renderer)
            // Make sure the render action is always asynchronously.
            setTimeout(function() { 
                render(token, tag, viewModel, attributeHash); 
            }, 0); 
        else
            throw new Error(
                "Backbone sub view renderer requires a 'renderer' attribute.");

        // Return the html place holder.
        return new Handlebars.SafeString(
            [ "<", tag," renderer-id='", token, "'></", tag,">" ].join(""));
    });

    function render(token, tag, model, hash) {
        require([ hash.renderer ], function(SubView) {
            var $placeHolder = $([ tag, "[renderer-id=", token, "]" ].join("")),
                subView = null;

            if (SubView.prototype instanceof Backbone.View) {
                subView = new Renderer({
                    token: token,
                    model: model,
                    attributes: _.omit(hash, "tag")
                });

                stage.push({
                    token: token,
                    view: subView
                });

                $placeHolder.replaceWith(renderer.$el);
            } else {
                throw new Error(
                    "The subview renderer must inherit from Backbone.View.");
            }
        });
    }
})();

Have a fresh tip? Share with Coderwall community!

Post
Post a tip
Did you know?

JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.

Security insights from Cside