• Like
Backbone
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Backbone

  • 1,755 views
Published

Backbone.js helps structure you javascript application code in a scalable way. …

Backbone.js helps structure you javascript application code in a scalable way.
In this keynote I demonstrate how to use it in a simple walk-through example, and discuss the advantages of using an MVC framework.

Published in Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
1,755
On SlideShare
0
From Embeds
0
Number of Embeds
8

Actions

Shares
Downloads
90
Comments
1
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Backbone.js How to write a well structured multi page web application Thursday, September 12, 13
  • 2. About • Ynon Perek • ynon@ynonperek.com • Find and download slides from: http://ynonperek.com Thursday, September 12, 13
  • 3. Unstructured JS • Developer Starts writing JS code • App gets big, developer gets angry Thursday, September 12, 13
  • 4. What We Want • Build apps like lego • Everything has a place Thursday, September 12, 13
  • 5. JS Solution • Separate Logic from View • Use a framework Thursday, September 12, 13
  • 6. MV* Frameworks Model View * Thursday, September 12, 13
  • 7. Available JS MV* • And a lot more... • Nice comparison: http://todomvc.com/ Thursday, September 12, 13
  • 8. Backbone.js • Created by Jeremy Ashkenas • Goal: Keep your code AWAY from the DOM Thursday, September 12, 13
  • 9. Reasons Why • Well tested and proven • Strong community • Simple: Almost no magic Thursday, September 12, 13
  • 10. Who’s Using Backbone ? Big list: http://backbonejs.org Thursday, September 12, 13
  • 11. Backbone (MV*) Concepts Thursday, September 12, 13
  • 12. Application Structure • Each “page” is just a div • “Page” can be a full page or partial <body>   <div class="page">     <h1>About Page</h1>   </div>   <div class="page">     <h1>Main Page</h1>   </div>   <div class="page">     <h1>Item Info</h1>   </div>   </body> Thursday, September 12, 13
  • 13. Application Structure • Navigating in the app is just calling a route function • Route function slides divs in-and-out help: function() {   alert('What can I help you with ?'); } Thursday, September 12, 13
  • 14. Application Structure • Implementing Client-side logic • Models “know” • Views “show” Thursday, September 12, 13
  • 15. Application Structure Model View DOM Store Data Renders Data Thursday, September 12, 13
  • 16. Models • Models store your data • Models have no visual representation • Functionality for managing changes Thursday, September 12, 13
  • 17. Views • A View provides the visual representation of a model Task Model Thursday, September 12, 13
  • 18. Collections • Models are usually grouped in collections * Task Model * Task Model * Task Model Daily Tasks Walk the dog Water the plans Thursday, September 12, 13
  • 19. Backbone Benefits • Good separation of concerns • Best for large client- side applications Thursday, September 12, 13
  • 20. What Backbone Is Not • It’s not a framework • So it’s ok to use only parts of it Thursday, September 12, 13
  • 21. What Backbone Is Not • It’s not for small apps that just “show data” • Backbone assumes client-side logic Thursday, September 12, 13
  • 22. What Backbone Is Not • It will never get in your way :) Thursday, September 12, 13
  • 23. Coding Time Thursday, September 12, 13
  • 24. Todo App • Model for each task • View for each task • Main application view Thursday, September 12, 13
  • 25. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Thursday, September 12, 13
  • 26. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Define a new model Thursday, September 12, 13
  • 27. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Set default values Thursday, September 12, 13
  • 28. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Define a new View Thursday, September 12, 13
  • 29. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Specify HTML element Thursday, September 12, 13
  • 30. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Define Event Handlers name of a method that will be called when the view is clicked Thursday, September 12, 13
  • 31. View Rendering • render() method of a view is used to render it to HTML • Usually implemented with client side template engine Thursday, September 12, 13
  • 32. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Define Render Function Thursday, September 12, 13
  • 33. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Paint The View onto HTML Thursday, September 12, 13
  • 34. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Handlebars is used as a template engine Thursday, September 12, 13
  • 35. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, initialize is called from a view’s constructor Thursday, September 12, 13
  • 36. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, We use it to bind event handlers on the model Thursday, September 12, 13
  • 37. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, Implementing the clicks handler Thursday, September 12, 13
  • 38. Main App View     global.views.AppView = Backbone.View.extend({         el: $('body'),         events: {             "click .add-btn": "add_task"         },         add_task: function() {             var task_description = this.$el.find('input').val();             var tm = new global.models.Task({ text: task_description });             var tv = new global.views.TaskView({model: tm});             this.$el.find('ul').append(tv.render().el);             this.$el.find('input').val('');         }     }); Thursday, September 12, 13
  • 39. Take Aways • Models keep data • Views show data • Views listen for model changes using on • Views listen for DOM changes using events Thursday, September 12, 13
  • 40. Lab • Add a “Priority” field to a task • Render high priority tasks in red, medium priority tasks in yellow and normal in green Thursday, September 12, 13
  • 41. Backbone Router • A Router connects URL with application state • This allows internal bookmarking and history management Thursday, September 12, 13
  • 42. Hello Router • You only need one • Defines routes and handlers var router = new (Backbone.Router.extend({   routes: {     '' : 'home',     'help' : 'help'   },     home: function() {     alert('WElcome home');   },     help: function() {     alert('What can I help you with ?');   } }))();   Backbone.history.start({ pushState: true } ); Thursday, September 12, 13
  • 43. Changing State • Use router.navigate( url ) to change state • Pass { trigger: true } if you need to also trigger the route Thursday, September 12, 13
  • 44. Demo • Let’s add a View Task page • Shows a specific task in details • Then connect the pages using a router Thursday, September 12, 13
  • 45. Server Side Models How to get server data using Backbone Models Thursday, September 12, 13
  • 46. Models & The Server • Set the urlRoot property of a model to allow it to sync with your server Thursday, September 12, 13
  • 47. Models & The Server Model Id Model Method HTTP Method Url id == 1 .fetch() GET /todos/1 id == 1 .save() PUT /todos/1 no id .fetch() GET /todos no id .save() POST /todos Thursday, September 12, 13
  • 48. Server Events • request event is triggered when sync starts • change event is triggered when an attribute value has changed • sync event is triggered when save is completed (i.e. data is saved on server) Thursday, September 12, 13
  • 49. Server URLs • POST /items => return a new item • GET /items/id => return an existing item by its id • PUT /items/id => change existing item by its id Thursday, September 12, 13
  • 50. Demo: https://github.com/ynonp/mobileweb- examples/tree/master/ajax/Backbone Thursday, September 12, 13
  • 51. Q & A Thursday, September 12, 13
  • 52. Collections Thursday, September 12, 13
  • 53. Collections • Groups of models • Add/Remove events • Sync from server Thursday, September 12, 13
  • 54. Collections Feed The Zombie Plant The Brainz Do The Zombie Walk Todos Collection Todo Models Thursday, September 12, 13
  • 55. Collection Actions • col.length : number of models in the collection • col.add(m) : add a model • col.remove(m) : remove a model Thursday, September 12, 13
  • 56. Collection Actions • col.at( index ) : get a model at a specific index • col.get( id ) : get a model by its id Thursday, September 12, 13
  • 57. Collection Actions • reset( array_of_models ) : sets the collection’s data Thursday, September 12, 13
  • 58. Collections Demo • Add a Tasks collection • Add a Counter view • Show active tasks count Thursday, September 12, 13
  • 59. Collections     global.models.TasksGroup = Backbone.Collection.extend({         model: global.models.Task     }) Define a new collection A collection needs to create objects, so we must provide the type as a class Thursday, September 12, 13
  • 60. Collection Views • It’s ok to create a view for a collection • Just pass in the collection to the view’s new method • Render delegates its job to subviews • Demo: Create a collection view for TasksGroup Thursday, September 12, 13
  • 61. Collection Views render: function() {   var $el = this.$el;     $el.html('');     this.collection.forEach(function(model) {     var v = new app.views.Task( { model: model } );     $el.append( v.render() );   });     return $el; }, Thursday, September 12, 13
  • 62. Collection Views render: function() {   var $el = this.$el;     $el.html('');     this.collection.forEach(function(model) {     var v = new app.views.Task( { model: model } );     $el.append( v.render() );   });     return $el; }, Pop Quiz: What can go wrong ? Thursday, September 12, 13
  • 63. Managing Subviews • If subviews also listen for model events, you will need to stop listening before removing the container view • Solution: keep a list of subviews in container Thursday, September 12, 13
  • 64. More Collection Views • Same data, different views • Let’s create a counter view • Show total number of tasks Thursday, September 12, 13
  • 65. Collections        initialize: function() {             var cv = new global.views.CounterView( { tasks: this.tasks }).render();             this.$el.append( cv.el );             this.tasks.on('add', cv.render, cv );             this.tasks.on('remove', cv.render, cv);         }, In appview.js Collections trigger events when models are added or removed Thursday, September 12, 13
  • 66. Collections    global.views.CounterView = Backbone.View.extend({         tagName: 'div',         className: 'counter',         initialize: function(opts) {             this.tasks = opts.tasks;         },         render: function() {             console.dir(this.el);             this.$el.html( this.template( { count: this.tasks.length }));             return this;         },         template: Handlebars.compile( $('#counter-template').html() )     }); Thursday, September 12, 13
  • 67. Lab • Modify CounterView so it will also display the number of unfinished tasks Thursday, September 12, 13
  • 68. Other Collection Methods • forEach (function(item) { ... } ) • find • filter • include • toArray Thursday, September 12, 13
  • 69. Collection and Server • Retrieve a collection from the server using fetch() • url is a property of collection • change event is triggered if server state is different Thursday, September 12, 13
  • 70. Collections Server URLs • GET /items => returns all items Thursday, September 12, 13
  • 71. Collection Events • reset event is triggered after fetch() or reset() • add() event is triggered when a model is added to a collection • remove() event is triggered when a model is removed from a collection Thursday, September 12, 13
  • 72. Q & A Thursday, September 12, 13
  • 73. Extending Backbone • Nested Collections • Pagination • Data Binding • Forms Thursday, September 12, 13
  • 74. Extending Backbone • Backbone is easy to extend: • You can add functions to the Backbone namespace • You can override Backbone’s methods Thursday, September 12, 13
  • 75. Try This • Add function toggle() to Backbone.Model to toggle bool values (true / false) Thursday, September 12, 13
  • 76. Try This • Create a TemplateView that acts like a Backbone.View with a simple template rendering functionality built-in Thursday, September 12, 13
  • 77. Backbone Extensions • JS Libs that extend Backbone • Really long list at: https://github.com/jashkenas/backbone/ wiki/Extensions,-Plugins,-Resources Thursday, September 12, 13
  • 78. Nested Collections • A collection that “has” another collection • Example: Inbox and Messages Thursday, September 12, 13
  • 79. Nested Approach Inbox Sent Drafts Models Mail Collection Thursday, September 12, 13
  • 80. Nested Approach Inbox Sent Drafts Models msg1 msg2 msg3 Models Thursday, September 12, 13
  • 81. Let’s Code This • Models: • Mailbox model • Message model • Collections: • Mailbox collection (for messages) • Folders collection (for mailboxes) Thursday, September 12, 13
  • 82. This works. But... • Given a message item, can you tell in which mailbox it is ? • How do you move a message from one inbox to another ? Thursday, September 12, 13
  • 83. Backbone-Relational • A plugin for managing relations between collections • Adds RelationalModel • http://backbonerelational.org/ Thursday, September 12, 13
  • 84. Q & A Thursday, September 12, 13
  • 85. Pagination • How would you implement pagination ? Thursday, September 12, 13
  • 86. Pagination • Collection only stores partial data • Add methods to collection: • goToNextPage() • goToPreviousPage() • goToPage() Thursday, September 12, 13
  • 87. Pagination • Need to override Backbone.sync to allow sending custom parameters to the server Thursday, September 12, 13
  • 88. Backbone.Sync • sync(method, model, [options]) • method: create / read / update / delete • model: model or collection • options: success and error callbacks Thursday, September 12, 13
  • 89. Backbone.Sync options • Use a global Backbone.sync to enable application wide overriding • Use a model/collection specific sync to have only that collection use your sync Thursday, September 12, 13
  • 90. Backbone.Sync Demo • Let’s write a cacheable model that adds two methods: • cache() • invalidate() • After cache(), all read requests should return the cached copy Thursday, September 12, 13
  • 91. Lab: Fill in the missing parts Backbone.CachedModel = Backbone.Model.extend({   cache: function() {   },     invalidate: function() {   },     sync: function(method, model, opts) {   } }); Thursday, September 12, 13
  • 92. Take Aways • Backbone.sync allows full control on the syncing process • If you just need to add functionality, consider listening for sync events Thursday, September 12, 13
  • 93. Pagination • Use a custom (paginated) collection • Add a sync method so it’ll send your pagination params to the server • AND Someone already did it :) Thursday, September 12, 13
  • 94. The Backbone Way • A special collection is added using the Paginator plugin • Backbone.Paginator.requestPager Thursday, September 12, 13
  • 95. Other Params • Paginated Collection needs: • paginator_core: an object describing how to interact with the server • paginator_ui: an object describing how to display the info • server_api: an object describing the parameters to send • Code: https://github.com/backbone- paginator/backbone.paginator Thursday, September 12, 13
  • 96. Demo • https://github.com/backbone-paginator/ backbone.paginator/tree/master/ examples/request-paging Thursday, September 12, 13
  • 97. Q & A Thursday, September 12, 13
  • 98. Other Plugins • Backbone.localStorage will let you store your models locally https://github.com/jeromegn/ Backbone.localStorage Thursday, September 12, 13
  • 99. Other Plugins • Backbone Forms will automatically create form controls for you • Also adds validation code • https://github.com/powmedia/ backbone-forms Thursday, September 12, 13
  • 100. Other Plugins • Backbone Stickit will let you have two- ways data binding for your views • http://nytimes.github.io/backbone.stickit/ Thursday, September 12, 13
  • 101. Extending Backbone • Extending Backbone is easy • Just create more models, views or controllers • Sometimes you’ll need to override Backbone methods Thursday, September 12, 13
  • 102. Benefits • Lifts big apps • Scalable and very stable • No magic • Extensible Thursday, September 12, 13
  • 103. Dark Side • Not suitable for small apps • Can be confusing for new developers • Can sometimes add clutter Thursday, September 12, 13
  • 104. Thank You • Ynon Perek • me@ynonperek.com • ynonperek.com Thursday, September 12, 13