Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Introduction to Backbone.js & Marionette.js

783 visualizaciones

Publicado el

Webinar presentation http://www.returnonintelligence.ru/webinars/backbone-and-marionette-js/

Publicado en: Software
  • Inicia sesión para ver los comentarios

Introduction to Backbone.js & Marionette.js

  1. 1. Core Systems Transformation Solutions Backbone & Marionette Tutor: Dmitry Grachikov, ROI
  2. 2. 1 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Frontend Application var html = "<div>" + "<span>" + data + "</span>" + "</div>"; $('#container').html(html); $('#contaner').append( $('<div></div>').append( $('<span></span>').html(data) ) ); $('span').on('click', function(e) { // do something... $(this).addClass('some-class'); // do something again... });
  3. 3. 2 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Frontend Application Benefits: • Easy for small amount of code • "Fast" development Drawbaks: • Complexity grows very fast • Hard to understand for medium and large codebase • Specifically to JavaScript: "Callback-Hell" • Hard to maintain • Tight coupling with HTML • …
  4. 4. 3 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Frontend Application Benefits: • Easy for small amount of code • "Fast" development Drawbaks: • Complexity grows very fast • Hard to understand for medium and large codebase • Specifically to JavaScript: "Callback-Hell" • Hard to maintain • Tight coupling with HTML • …
  5. 5. 4 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that "simple" approach with jQuery cannot solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  6. 6. 5 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that jQuery can't solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  7. 7. 6 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that jQuery can't solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  8. 8. 7 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that jQuery can't solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  9. 9. 8 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that jQuery can't solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  10. 10. 9 Return on Intelligence, Inc. ©2014 All Rights Reserved. "Simple" Application Improvements • Assume that jQuery can't solve all problems • Separate View from business logic – Solve problem with custom solution – Using effective architectural pattern (for example MVC, MVVM, …) • Create own realization • Use proven framework
  11. 11. 10 Return on Intelligence, Inc. ©2014 All Rights Reserved. Proven Framework vs Custom Solution Custom Solution Proven Framework + Suitable to the project + No time for learning - Implementation take a long time - After a while can be that new concepts cannot be added + Ready to use + Well documented + Community - Requires time for learning - Can take a time to figure out that framework is not suitable to the project
  12. 12. 11 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Marionette.js Models Collections Views ItemView CollectionView CompositeView LayoutView
  13. 13. 12 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Backbone.js gives structure to web application
  14. 14. 13 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Model Definition var EmployeeModel = Backbone.Model.extend({ defaults: { id: null, name: null, surname: null, dateOfEmployment: null, ... } }); var employee = new EmployeeModel({ name: 'John', surname: 'Johnson', dateOfEmployment: '2000-01-05', ... });
  15. 15. 14 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Model Initialization var EmployeeModel = Backbone.Model.extend({ defaults: { id: null, name: null, surname: null, dateOfEmployment: null, ... } }); var employee = new EmployeeModel({ name: 'John', surname: 'Johnson', dateOfEmployment: '2000-01-05', ... });
  16. 16. 15 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Model Events employee.on('change', function(model) { console.log('Employee changed'); }); employee.on('change:name', function(model) { console.log('Name changed ' + model.previous('name') + ' -> ' + model.get('name')); }); employee.set('name', 'Peter'); employee.set({ name: 'John', surname: 'Peterson' });
  17. 17. 16 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Model Events employee.on('change', function(model) { console.log('Employee changed'); }); employee.on('change:name', function(model) { console.log('Name changed ' + model.previous('name') + ' -> ' + model.get('name')); }); employee.set('name', 'Peter'); employee.set({ name: 'John', surname: 'Peterson' });
  18. 18. 17 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Models REST var EmployeeModel = Backbone.Model.extend({ urlRoot: 'http://api.dev/employees', ... }); var employee = new EmployeeModel({ name: 'John', surname: 'Johnson', ... }); employee.save({ ... }); urlRoot 00020000009222iik0
  19. 19. 18 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Models REST var EmployeeModel = Backbone.Model.extend({ urlRoot: 'http://api.dev/employee', ... }); var employee = new EmployeeModel({ name: 'John', surname: 'Johnson', ... }); employee.save({ ... }); urlRoot POST /employee Response: { "id": 1, ... }
  20. 20. 19 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Models REST employee.fetch(); employee.save({ name: "Some name", ... }); employee.destroy(); GET /employee/1 PUT /employee/1 { "name": "Some name", ... } DELETE /employee/1
  21. 21. 20 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Collection Definition var EmployeeCollection = Backbone.Collection.extend({ model: EmployeeModel }); var employees = new EmployeeCollection([ {id: 1, name: 'John', surname: 'Johnson'}, {id: 2, name: 'Peter', surname: 'Peterson'} ]);
  22. 22. 21 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Collection Initialization var EmployeeCollection = Backbone.Collection.extend({ model: EmployeeModel }); var employees = new EmployeeCollection([ {id: 1, name: 'John', surname: 'Johnson'}, {id: 2, name: 'Peter', surname: 'Peterson'} ]);
  23. 23. 22 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Filling Collection employees.add({id: 1, name: 'John', ...}); or employees.add(employee);
  24. 24. 23 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Remove Data From Collection employees.remove(1); //remove by id or employees.remove(employee); //remove by model
  25. 25. 24 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Access Collection Data var first = employees.first(); var second = employees.at(1); //Get second element var peter = employees.get(2); //Search by id var john = employees.findWhere({name: 'John'}); var johns = employees.where({name: 'John'});
  26. 26. 25 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Collection Events employees.on('add', function(model, collection) { console.log('New employee added'); }); employees.on('remove', function(model, collection) { console.log('Employee removed'); });
  27. 27. 26 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Collections REST var Employees = Backbone.Collection.extend({ url: 'http://api.dev/employees', ... }); Define url
  28. 28. 27 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Collections REST employees.fetch(); employees.create({ name: "Ivan", name: "Petrov" }); employees.at(0).destroy(); GET /employees POST /employees { "name": "Ivan", ... } DELETE /employees/:id
  29. 29. 28 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js View Definition Backbone View
  30. 30. 29 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js View Definition var EmployeeView = Backbone.View.extend({ el: 'table tbody', render: function() { var templateEl = '#template', template = _.template(templateEl.html()), html = template({users: this.collection}); this.$el.html(html); } });
  31. 31. 30 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js Template <script type="text/template" id="template"> <% users.each(function(user) { %> <tr> <td><%= user.get('id') %></td> <td><%= user.get('name') %></td> <td><%= user.get('surname') %></td> <td><%= user.get('position') %></td> <td><%= user.get('dateOfEmployment') %></td> </tr> <% }) %> </script>
  32. 32. 31 Return on Intelligence, Inc. ©2014 All Rights Reserved. Backbone.js View Render var employees = new EmployeeCollection(...); var view = new EmployeeView({ collection: employees }); view.render();
  33. 33. 32 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js Marionette.Js Marionette simplifies your Backbone application code with robust views and architecture solutions.
  34. 34. 33 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView Definition var EmployeeItemView = Marionette.ItemView.extend({ el: 'table tbody', template: '#template-user' });
  35. 35. 34 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView vs Backbone View var EmployeeItemView = Marionette.ItemView.extend({ el: 'table tbody', template: '#template-user' }); var EmployeeView = Backbone.View.extend({ el: 'table tbody', render: function() { var templateEl = '#template', template = _.template(templateEl.html()), html = template({users: this.collection}); this.$el.html(html); } });
  36. 36. 35 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView Template <script type="text/template" id="template-user"> <tr> <td><%= id %></td> <td><%= name %></td> <td><%= surname %></td> <td><%= position %></td> <td><%= dateOfEmployment %></td> <td> <a href="#" class="promote"> Promote </a> </td> </tr> </script>
  37. 37. 36 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView. Add UI Element var EmployeeItemView = Marionette.ItemView.extend({ ... ui: { promote: '.promote' }, events: { 'click @ui.promote': 'onPromoteClick' }, modelEvents: { 'change': 'render' }, onPromoteClick: function(e) { e.preventDefault(); this.model.set('position', 'Senior Developer'); } });
  38. 38. 37 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView. Add Click Handling var EmployeeItemView = Marionette.ItemView.extend({ ... ui: { promote: '.promote' }, events: { 'click @ui.promote': 'onPromoteClick' }, modelEvents: { 'change': 'render' }, onPromoteClick: function(e) { e.preventDefault(); this.model.set('position', 'Senior Developer'); } });
  39. 39. 38 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView. Add Model Change Render var EmployeeItemView = Marionette.ItemView.extend({ ... ui: { promote: '.promote' }, events: { 'click @ui.promote': 'onPromoteClick' }, modelEvents: { 'change': 'render' }, onPromoteClick: function(e) { e.preventDefault(); this.model.set('position', 'Senior Developer'); } });
  40. 40. 39 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js ItemView Initialization var employee = new EmployeeModel(...); var view = new EmployeeItemView({ model: employee }); view.render();
  41. 41. 40 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CollectionView Definition var CollectionView = Marionette.CollectionView.extend({ el: 'table tbody', childView: EmployeeItemView });
  42. 42. 41 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CollectionView Initialization var employees = new EmployeeCollection(); var view = new CollectionView({ collection: employees }); view.render();
  43. 43. 42 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView Definition CompositeView = CollectionView + ItemView
  44. 44. 43 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView Definition var CompositeView = Marionette.CompositeView.extend({ el: 'div#users', template: '#template', childView: EmployeeItemView, childViewContainer: 'table tbody' });
  45. 45. 44 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView Template <script type="text/template" id="template"> <table class="table"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Surname</th> <th>Position</th> <th>Date of employment</th> <th>Action</th> </tr> </thead> <tbody> <!-- Employees will be rendered here --> </tbody> </table> </script>
  46. 46. 45 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView ChildView var CompositeView = Marionette.CompositeView.extend({ el: 'div#users', template: '#template', childView: EmployeeItemView, childViewContainer: 'table tbody' });
  47. 47. 46 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView ChildViewContainer var CompositeView = Marionette.CompositeView.extend({ el: 'div#users', template: '#template', childView: EmployeeItemView, childViewContainer: 'table tbody' });
  48. 48. 47 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. Data Sort EmployeesCollection
  49. 49. 48 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. Data Sort Comparator(E1,E2) EmployeesCollection
  50. 50. 49 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. Data Sort Comparator(E1,E2) EmployeesCollection SortModel
  51. 51. 50 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. Data Sort Comparator(E1,E2) EmployeesCollection SortModel CompositeView
  52. 52. 51 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js EmployeesCollection Comparator comparator: function(employee1, employee2) { //returns -1, 0, 1 }
  53. 53. 52 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. DataSort UI var CompositeView = Marionette.CompositeView.extend({ ui: { sort: 'span[data-sortBy]' }, events: { 'click @ui.sort': 'onSortLinkClick' }, onSortLinkClick: function(e) { ... } ... });
  54. 54. 53 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView. Sort Handler ... onSortLinkClick: function(e) { var $el = $(e.currentTarget), sortBy = this.model.get('sortBy'), sortOrder = this.model.get('sortOrder'); this.model.set({ sortBy: $el.data('sortby'), sortOrder: sortBy == $el.data('sortby') ? (-sortOrder || 1) : 1 }); this.collection.sort(); }, ...
  55. 55. 54 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js CompositeView Initialization var view = new CompositeView({ el: '#users', collection: employees, model: sortModel }); view.render(); var sortModel = new SortModel({ sortBy: null, sortOrder: null });
  56. 56. 55 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js Views Communication <Employee Form /> <Employee List /> EditSave/Cancel Add
  57. 57. 56 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js LayoutView Definition LayoutView = View * Region
  58. 58. 57 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js LayoutView var LayoutView = Marionette.LayoutView.extend({ template: ..., ui: ..., events: ..., regions: { employees: '#employees', employeeForm: '#employee-form' }, ... createEmployeeFormView: function(model) { ... } });
  59. 59. 58 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js LayoutView. Region+View var LayoutView = Marionette.LayoutView.extend({ ... enteremployeeFormMode: function() { ... this.showChildView('employeeForm', this.createNewEmployeeView()); } ... });
  60. 60. 59 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js LayoutView. View Events var LayoutView = Marionette.LayoutView.extend({ template: ..., ui: ..., events: ..., createEmployeeFormView: function(model) { var view = new EmployeeFormView({ model: model || new EmployeesModel() }); view.on('cancel', this.onAddCancel.bind(this)); view.on('save', this.onEmployeeSave.bind(this)); return view; } });
  61. 61. 60 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js LayoutView. View Events var LayoutView = Marionette.LayoutView.extend({ template: ..., ui: ..., events: ..., createEmployeeFormView: function(model) { var view = new EmployeeFormView({ model: model || new EmployeesModel() }); view.on('cancel', this.onAddCancel.bind(this)); view.on('save', this.onEmployeeSave.bind(this)); return view; } });
  62. 62. 61 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js Conclusions Marionette.js: • Offers rich View functionality • Makes realization of View easier even then in "simple" approach • Allows to create reusable components • …
  63. 63. 62 Return on Intelligence, Inc. ©2014 All Rights Reserved. Marionette.js Appendix: One To Many Relation var employeesView = new OneToManyCompositeView(...); var notes = new NoteCollection(); var notesView = new OneToManyNotesCompositeView({ collection: notes }); employeesView.on('childview:show:notes', function(view) { notesView.model = view.model; notesView.render(); notes.url = 'http://.../' + view.model.get('id'); notes.fetch(); });

×