$(function () {
$(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);
});