Created
February 26, 2012 13:58
-
-
Save kizzx2/1916961 to your computer and use it in GitHub Desktop.
Minimal single-file Backbone.js demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script src="require.js"></script> | |
| <script> | |
| require(['jquery', 'underscore', 'backbone'], | |
| function($) | |
| { | |
| var UBlog = {}; | |
| if(!localStorage.UBlog) | |
| localStorage.UBlog = JSON.stringify({ posts: {}}); | |
| function resync() | |
| { | |
| localStorage.UBlog = JSON.stringify(storage); | |
| } | |
| var postStore = | |
| { | |
| create: function(model, options) | |
| { | |
| var id = new Date().getTime() + ""; | |
| model.set({id: id}); | |
| storage.posts[model.id] = model; | |
| resync(); | |
| options.success(model, "OK"); | |
| }, | |
| read: function(model, options) | |
| { | |
| options.success(new UBlog.Post(storage.posts[model.id]), "OK"); | |
| }, | |
| update: function(model, options) | |
| { | |
| storage.posts[model.id] = model; | |
| resync(); | |
| options.success(model, "OK"); | |
| }, | |
| delete: function(model, options) | |
| { | |
| delete storage.posts[model.id]; | |
| resync(); | |
| options.success(model, "OK"); | |
| } | |
| }; | |
| var postCollectionStore = | |
| { | |
| read: function(model, options) | |
| { | |
| options.success(_(storage.posts).map(function(v, k) | |
| { | |
| return v; | |
| }), "OK"); | |
| }, | |
| }; | |
| $(function() | |
| { | |
| UBlog.Post = Backbone.Model.extend( | |
| { | |
| url: '/posts', | |
| validate: function(attrs) | |
| { | |
| if(!attrs.title || attrs.title.length < 5) | |
| return "Title is too short"; | |
| if(!attrs.body || attrs.body.length < 5) | |
| return "Body is too short"; | |
| } | |
| }); | |
| UBlog.PostCollection = Backbone.Collection.extend( | |
| { | |
| url: '/posts', | |
| model: UBlog.Post, | |
| }); | |
| UBlog.PostView = Backbone.View.extend( | |
| { | |
| events: | |
| { | |
| 'click button.delete': 'delete' | |
| }, | |
| initialize: function() | |
| { | |
| this.model.bind('remove', _.bind(this.onRemove, this)); | |
| }, | |
| onRemove: function() | |
| { | |
| $(this.el).remove(); | |
| }, | |
| template: _.template( | |
| "<strong><%=title%></strong>" + | |
| "<button class='delete'>Delete</button>" + | |
| "<p><%=body%></p>"), | |
| delete: function() | |
| { | |
| this.model.destroy(); | |
| }, | |
| render: function() | |
| { | |
| $(this.el).html(this.template(this.model.attributes)); | |
| return this; | |
| } | |
| }); | |
| UBlog.PostListView = Backbone.View.extend( | |
| { | |
| initialize: function(options) | |
| { | |
| this.appEl = options.appEl; | |
| this.el = $(this.appEl).find('.posts'); | |
| this.collection.bind('add', _.bind(this.onAdd, this)); | |
| }, | |
| onAdd: function(item) | |
| { | |
| $(this.el).append(new UBlog.PostView({model: item}).render().el); | |
| }, | |
| render: function() | |
| { | |
| var self = this; | |
| $(this.el).html(''); | |
| this.collection.each(function(post) | |
| { | |
| $(self.el).append(new UBlog.PostView({model: post}).render().el); | |
| }); | |
| return this; | |
| } | |
| }); | |
| var posts = new UBlog.PostCollection(); | |
| UBlog.Router = Backbone.Router.extend( | |
| { | |
| routes: | |
| { | |
| '': 'index', | |
| 'clear': 'clear', | |
| }, | |
| clear: function() | |
| { | |
| localStorage.UBlog = JSON.stringify({posts:{}}); | |
| this.navigate('', {trigger: true}); | |
| }, | |
| initialize: function(options) | |
| { | |
| this.appEl = options.appEl; | |
| }, | |
| error: function(message) | |
| { | |
| $(this.el).find('.errors').text(message); | |
| }, | |
| index: function() | |
| { | |
| storage = JSON.parse(localStorage.UBlog); | |
| var self = this; | |
| posts.reset(); | |
| posts.fetch( | |
| { | |
| success: function(xs, resp) | |
| { | |
| new UBlog.PostListView( | |
| { | |
| collection: xs, | |
| appEl: self.appEl | |
| }).render(); | |
| }, | |
| error: function(xs, resp) | |
| { | |
| self.error("Failed to fetch posts"); | |
| }, | |
| }); | |
| } | |
| }); | |
| Backbone.sync = function(method, model, options) | |
| { | |
| console.log("Dispatch", method, model, options); | |
| if(model instanceof UBlog.PostCollection) | |
| return postCollectionStore[method](model, options); | |
| else if(model instanceof UBlog.Post) | |
| return postStore[method](model, options); | |
| else | |
| options.error(model, "Unknown model"); | |
| }; | |
| var router = new UBlog.Router( | |
| { | |
| appEl: $('#AppMain') | |
| }); | |
| Backbone.history.start(); | |
| $('form').submit(function() | |
| { | |
| try | |
| { | |
| new UBlog.Post( | |
| { | |
| title: $('form [name=title]').val(), | |
| body: $('form [name=body]').val() | |
| }).save({}, | |
| { | |
| success: function(model, resp) | |
| { | |
| posts.add(model); | |
| }, | |
| error: function(model, resp) | |
| { | |
| alert(resp); | |
| } | |
| }); | |
| router.navigate('', {trigger: true}); | |
| } | |
| catch(e) { console.log(e); } | |
| return false; | |
| }); | |
| }); | |
| }); | |
| </script> | |
| </head> | |
| <body> | |
| <div id="AppMain"> | |
| <div class="errors"></div> | |
| <div class="posts"></div> | |
| <form id="NewForm"> | |
| <label>Title <input type="text" name="title" /></label><br /> | |
| <label>Body<br /><textarea name="body"></textarea></label><br /> | |
| <input type="submit" /> | |
| </form> | |
| <a href="#clear">Clear all posts</a> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment