Skip to content

Instantly share code, notes, and snippets.

@jacobthemyth
Created February 19, 2015 17:06
Show Gist options
  • Select an option

  • Save jacobthemyth/4e1d36678616b7dd203d to your computer and use it in GitHub Desktop.

Select an option

Save jacobthemyth/4e1d36678616b7dd203d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app-container"></div>
<script type="text/template" data-template-name="index">
<h1>Blog Title</h1>
</script>
<script type="text/template" data-template-name="post-item">
<a href="#posts/<%= objectId %>"><%= title %></a>
</script>
<script type="text/template" data-template-name="post-create">
<button class="js-create">Create</button>
<input class="js-title" type="text" placeholder="title">
<textarea class="js-body" id="" name="" cols="30" rows="10"></textarea>
</script>
<script type="text/template" data-template-name="show-post">
<h1><%= title %></h1>
<p><%= body %></p>
<button>Edit</button>
<button>Delete</button>
</script>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/underscore/underscore.js"></script>
<script src="bower_components/backbone/backbone.js"></script>
<script src="main.js"></script>
</body>
</html>
(function(){
var Post = Backbone.Model.extend({
idAttribute: 'objectId',
defaults: {
title: '',
body: ''
}
});
var PostsCollection = Backbone.Collection.extend({
model: Post,
url: "https://api.parse.com/1/classes/Post",
parse: function(response){
return response.results;
}
});
// -------------
// Views / (Presentation / Interation)
// -------------
// This is a good practice to create a `close` function on a view prototype
// so that it's available in all views
// This is the sort of thing that's definitely acceptable to just copy
var BaseView = Backbone.View.extend({
close: function(){
if(_.isArray(this.childViews)){
_.invoke(this.childViews, 'close');
}
this.remove();
}
});
var PostsIndexView = BaseView.extend({
template: _.template($('[data-template-name=index]').text()),
initialize: function(){
this.listView = new PostsListView({collection: this.collection});
this.createView = new PostCreateView({collection: this.collection});
},
render: function(){
this.$el.html(this.template());
this.listView.render();
this.$el.append(this.listView.el);
this.createView.render();
this.$el.append(this.createView.el);
return this;
},
close: function(){
this.listView.close();
this.createView.close();
this.remove();
}
});
var PostsListView = BaseView.extend({
tagName: 'ul',
initialize: function(){
this.listenTo(this.collection, 'sync', this.render);
},
render: function(){
this.$el.empty();
this.renderChildren();
return this;
},
renderChildren: function(){
this.childViews = this.collection.map(function(post){
return new PostItemView({model: post});
});
var self = this;
_.each(this.childViews, function(view){
view.render();
self.$el.append(view.el);
});
},
});
var PostItemView = BaseView.extend({
tagName: 'li',
template: _.template($('[data-template-name=post-item]').text()),
initialize: function(){
this.listenTo(this.model, 'change:title', this.render);
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
});
var PostCreateView = BaseView.extend({
tagName: 'form',
template: _.template($('[data-template-name=post-create]').text()),
events: {
'click .js-create': 'createPost',
},
createPost: function(e){
e.preventDefault();
var title = this.$('.js-title').val();
var body = this.$('.js-body').val();
this.collection.create({title: title, body: body});
this.$('.js-title').val('');
this.$('.js-body').val('');
},
render: function(){
this.delegateEvents();
this.$el.html(this.template());
return this;
}
});
var ShowPostView = BaseView.extend({
template: _.template($('[data-template-name=show-post]').text()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
}
});
// -------------
// Router / Application State
// -------------
var AppRouter = Backbone.Router.extend({
routes: {
'': 'index',
'posts/:id': 'showPost'
},
initialize: function(){
this.postsCollection = new PostsCollection();
},
index: function(){
this.killZombies();
this.currentView = new PostsIndexView({
collection: this.postsCollection
});
this.currentView.render();
$('#app-container').html(this.currentView.el);
this.postsCollection.fetch();
},
showPost: function(id){
this.killZombies();
var self = this;
this.postsCollection.fetch().done(function(){
self.currentView = new ShowPostView({
model: self.postsCollection.get(id)
});
self.currentView.render();
$('#app-container').html(self.currentView.el);
});
},
killZombies: function(){
if(this.currentView) {
this.currentView.close();
delete this.currentView;
}
}
});
// -------------
// Configuration
// -------------
$.ajaxSetup({
headers: {
"X-Parse-Application-Id": "ZYQHOvrj5oPV8fGAN6M7x6m00ZNLtr5tpd3gzkFi",
"X-Parse-REST-API-Key": "0BRysAUoHF2WsbkYZh1DOosJS3Oi1uS31KozIKUz"
}
});
// -------------
// Glue code
// -------------
$(document).ready(function(){
window.router = new AppRouter();
Backbone.history.start();
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment