Skip to content

Instantly share code, notes, and snippets.

@c4urself
Created February 23, 2012 09:43
Show Gist options
  • Save c4urself/1891974 to your computer and use it in GitHub Desktop.
Save c4urself/1891974 to your computer and use it in GitHub Desktop.
Abstract view for Backbone
define([
'jquery',
'underscore',
'backbone',
'mustache'
], function($, _, Backbone, Mustache){
var view = Backbone.View.extend({
model: null,
template: null,
applyTemplatePlugins: true,
render: function() {
return this.renderView();
},
renderView: function(el, template, model, partials, helpers, data) {
el = el || this.el;
template = template || this.template;
partials = partials || this.partials || null;
model = model || this.model;
if (!el) {
throw new Error('el must be defined in view or as parameter');
}
if (!template) {
throw new Error('template must be defined in view or as parameter');
}
if (model instanceof Backbone.Model || model instanceof Backbone.Collection) {
model = model.toJSON();
}
if (this.enrichModel) {
model = this.enrichModel(model);
}
this.addTemplateHelperFunctions(model);
$(el).html(Mustache.to_html(template, model, partials));
this.applyTemplatePluginsToView();
return this;
},
addTemplateHelperFunctions: function(model) {
if (model) {
model.formatCurrency = function() {
return function(text, render) {
var value = Number(text).toFixed(2);
return render('€ ' + value.replace('.', ','));
};
};
}
},
applyTemplatePluginsToView: function() {
if (!this.applyTemplatePlugins) {return;}
this.$(".tooltip").tooltip();
},
updateAttribute: function(event) {
var el = event.currentTarget;
var attrs = {};
attrs[el.name] = el.value;
this.model.set(attrs);
},
rebindValidationToView: function(newView, currentView) {
currentView = currentView || this;
Backbone.Validation.unbind(currentView);
if (newView) {
Backbone.Validation.bind(newView);
}
},
fetch: function(options) {
options = options || {};
this.showLoader();
var successDefaultHandler = function(model, response) {
this.render();
if (this.fetchSuccessHandler) {
this.fetchSuccessHandler.apply(this, arguments);
}
};
options.success = wrapHandlerOrDefault(this, options.success, successDefaultHandler);
options.error = wrapHandlerOrDefault(this, options.error, errorDefaultHandler);
return this.model.fetch(options);
},
save: function(attrs, options) {
attrs = attrs || {};
options = options || {};
this.showLoader();
var successDefaultHandler = function(model, response) {
this.renderView();
if (this.saveSuccessHandler) {
this.saveSuccessHandler.apply(this, arguments);
}
};
options.success = wrapHandlerOrDefault(this, options.success, successDefaultHandler);
options.error = wrapHandlerOrDefault(this, options.error, errorDefaultHandler);
return this.model.save(attrs, options);
},
showLoader: function() {
$(this.el).loader('show');
},
hideLoader: function() {
$(this.el).loader('hide');
}
});
var wrapHandlerOrDefault = function(view, handler, defaultHandler) {
var wrappedHandler, newHandler;
wrappedHandler = handler || defaultHandler;
newHandler = function(model, response) {
wrappedHandler.apply(view, arguments);
view.hideLoader();
};
return newHandler;
};
var errorDefaultHandler = function(model, resp) {
if (_.isString(resp) || _.isArray(resp)) {
alert(resp);
}
else {
alert('TODO: Other error handling, e.g. serverside validation errors or connectivity issues');
console.log(arguments);
}
};
return view;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment