Skip to content

Instantly share code, notes, and snippets.

@Flushot
Last active December 18, 2015 17:39
Show Gist options
  • Select an option

  • Save Flushot/5820490 to your computer and use it in GitHub Desktop.

Select an option

Save Flushot/5820490 to your computer and use it in GitHub Desktop.
Backbone RequireJS boilerplate
require(['module', 'gevents'], function(module, gevents) {
var userView = new module.UserView();
var commentsView = new module.CommentsView({ el: $('#comments'), collection: [] });
var chris = new module.User({
first_name: 'Chris',
last_name: 'Lyon',
email: '[email protected]',
comments: [
{ message: 'testing' },
{ message: 'blah' }
]
});
gevents.trigger('showUser', chris);
});
define(function() {
return _.extend({}, Backbone.Events);
});
<h1>Sample template</h1>
<!-- Error message -->
<div class="error" style="display: none; color: red"></div>
<div id="comments">
<h2>Comments</h2>
<table>
<tbody data-bind="foreach: comments">
<tr>
<td><a class="show-user-action" data-bind="
text: user.first_name + ' ' + user.last_name,
attr: { 'data-id': user.id }"></a></td>
<td data-bind="text: message"></td>
</tr>
</tbody>
</table>
</div>
define(['exports', 'gevents', 'text!./user_editor.html'],
function(module, gevents, templateText) {
// User
module.User = Backbone.RelationalModel.extend({
idAttribute: '_id',
url: function() {
return '/users/' + this.get('id');
},
defaults: {
first_name: null,
last_name: null,
email: null
//others
},
relations: [
{
key: 'comments',
type: Backbone.HasMany,
relatedModel: 'module.OtherModel',
reverseRelation: {
key: 'user',
includeInJSON: 'id'
}
}
],
initialize: function() {
},
// Validation function (returns nothing if successful)
validate: function(attrs, options) {
if (!attrs.first_name) return 'First name is required';
if (!attrs.last_name) return 'Last name is required';
if (!attrs.email) return 'Email is required';
if (!attrs.email.match(/^.+@.+\.{2,}$/)) return 'Valid email is required';
}
});
module.UserList = Backbone.Collection.extend({
model: User,
url: '/users/',
comparator: function(user) {
return user.get('first_name') + user.get('last_name');
}
});
var users = new UserList();
users.fetch({ data: { active: true } });
// User comment
module.Comment = Backbone.RelationalModel.extend({
idAttribute: '_id',
defaults: {
message: null,
date: function() { return new Date() }
//user
},
validate: function(attrs, options) {
if (!attrs.message) return 'Message is required';
}
});
module.UserView = Backbone.View.extend({
tagName: 'div',
// UI events
events: {
'click .save-action': 'onSaveUser'
},
// Tag attributes
attributes: {
'class': ''
},
initialize: function() {
console.assert( this.model instanceof module.SomeModel );
_.bindAll(this, ['onModelChanged', 'onModelInvalid']);
this.model.on({
'invalid comments:invalid': this.onModelInvalid
});
gevents.on('showUser', this.onChangeUser, this);
if (this.model)
this.onChangeUser(this.model);
},
render: function() {
this.$el.html(
_.template(templateText),
this.model);
},
onChangeUser: function(user) {
ko.applyBindings(kb.viewModel(this.model), this.el);
this.model = user;
this.render();
},
// Validation failed
onModelInvalid: function(model, error) {
$('.error', this.el)
.html(error)
.show();
},
onSaveUser: function(e) {
var model = this.model;
if (!model.isValid()) {
alert('Error: ' + model.validationError);
}
model.save();
}
});
// Comments
module.CommentsView = Backbone.View.extend({
events: {
'click .show-user-action': 'onShowUser'
},
initialize: function() {
ko.applyBindings(kb.collectionObservable(this.collection, { view_model: kb.ViewModel }));
},
onShowUser: function(e) {
e.preventDefault();
var userId = $(this).data('id');
gevents.trigger('showUser', users.get(userId)));
}
});
});
<!-- User editor -->
<h2>User</h2>
<table>
<tbody>
<tr>
<td>First Name</td>
<td><input data-bind="value: first_name"/></td>
</tr>
<tr>
<td>Last Name</td>
<td><input data-bind="value: last_name"/></td>
</tr>
<tr>
<td>Email</td>
<td><input data-bind="value: email"/></td>
</tr>
</tbody>
</table>
<div calss="btn-group">
<button class="save-action" type="button">Save</button>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment