• model-binding.js

  • ¶
    $(function () {
  • ¶

    create a instance of Backbone Model with some default values.

        var BaseViewModel = new Backbone.Model();
        BaseViewModel.set({
                "firstName": "",
                "lastName": "",
                "salary": "",
                "pro": true
        });
  • ¶

    create a converter function, that formats the given value as money, for example 123 gets converted to $123.00, used by the money input.

        var salaryConverter = function (direction, value) {
            if (direction === "ModelToView") {
  • ¶

    format only when the direction is from model to view

                return accounting.formatMoney(value);
            } else {
  • ¶

    from view to model, just store the plain value

                return value;
            }
        };
  • ¶

    create a Backbone view

        var BaseView = Backbone.View.extend({
  • ¶

    local variable for model binder

            _modelBinder: undefined,
            initialize: function () {
  • ¶

    on view initialize, initialize _modelBinder

                this._modelBinder = new Backbone.ModelBinder();
            },
            close: function () {
  • ¶

    when view closes, unbind Model bindings

                this._modelBinder.unbind();
            },
            render: function () {
  • ¶

    when the view is rendered get the templated id from passed in options NOTE: templateId is not a property of Backbone or ModelBinder, its a custom parameter that we pass into view's constructor

               
                var templateId = "#" + this.options.templateId;
  • ¶

    construct the template

                var template = _.template($(templateId).html());
                var templateHTML = template();
  • ¶

    append it to current view

                this.$el.html(templateHTML);
  • ¶

    get the bindings attribute from passed options NOTE: bindings is not a property of Backbone, its a custom parameter that we pass into view's constructor

                var bindings = this.options.bindings;
  • ¶

    call modelBinder bind api to apply bindings on the current view

                this._modelBinder.bind(
                this.model /*the model to bind*/ ,
                this.el /*root element*/ ,
                bindings /*bindings*/ );
    
                return this;
            }
        });
  • ¶

    bindings for editor view: firstName attribute on the model to element with name property set to firstName lastName attribute on the model to element with name property set to lastName salary attribute on the model to element with name property set to salary, also passin a construction function, so that the value is formatted as money favSearch attribute on the model to element with name property set to favSearch

        var editorViewBindings = {
                "firstName": '[name = "firstName"]', 
                "lastName": '[name = "lastName"]',
                "salary": {
                selector: '[name = "salary"]',
                converter: salaryConverter
            },
                "pro": '[name = "pro"]',
                "favSearch": '[name = "favSearch"]'
        };
  • ¶

    instantiate the editor view by passing the model, tempalte id and bindings into the constructor

        var myEditorView = new BaseView({
            model: BaseViewModel,
            templateId: "editor-template",
            bindings: editorViewBindings
        });
  • ¶

    bindings for viewer view: firstName attribute on the model to element with name property set to firstName lastName attribute on the model to element with name property set to lastName salary attribute on the model to element with name property set to salary, also passin a construction function, so that the value is formatted as money favSearch attribute on the model to element with name property set to favSearch, Notice that there are two bindings here (set as an array), the reason for this is, on the preview view, we are binding favSearch to an anchor, so we want to update the anchor label as well as the 'href' property on the anchor. to achieve this we make use of 'elAttribute' in the bindings, which says that, bind favSearch to a el with name 'favSearch' and the attribute to bind this is 'href'.

        
        var viewerBindings = {
            "firstName": '[name = "firstName"]',
                "lastName": '[name = "lastName"]',
                "salary": {
                selector: '[name = "salary"]',
                converter: salaryConverter
            },
                "pro": '[name = "pro"]',
                "favSearch": [{
                selector: '[name = "favSearch"]',
                elAttribute: "href"
            }, {
                selector: '[name = "favSearch"]'
            }]
        }
  • ¶

    instantiate the viewer view by passing the model, tempalte id and bindings into the constructor

        var myViewerView = new BaseView({
            model: BaseViewModel,
            templateId: "viewer-template",
            bindings: viewerBindings
        });
  • ¶

    append both the Backbone views to the container

        $(".container").append(myEditorView.render().$el);
        $(".container").append(myViewerView.render().$el);
    
    });