backbone.js-init-lab

 backbone.js-init-lab

My backbone.js presentation at initLab. Code for the demos available at: https://github.com/RStankov/backbone-presentation

7a0e72a6f55811246bb5d9a946fd2e49?s=128

Radoslav Stankov

June 23, 2012
Tweet

Transcript

  1. Radoslav Stankov init Lab / SofiaJs 23/06/2012

  2. Who am I? @rstankov http://rstankov.com http://github.com/rstankov

  3. None
  4. None
  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. None
  14. None
  15. None
  16. None
  17. None
  18. None
  19. None
  20. None
  21. Model View Browser Controller Сървър

  22. Model View Browser Controller Сървър

  23. Model View Browser Controller Сървър

  24. Model View Browser Controller Сървър

  25. Model View Browser Controller Сървър

  26. Model View Browser Controller Сървър

  27. Model View Browser Controller Сървър

  28. Model View Browser Controller Сървър

  29. Model View Browser Controller Сървър

  30. Model View Browser Controller Сървър

  31. Model View Browser Controller Сървър

  32. Model View Browser Controller Сървър

  33. Model View Browser Controller Сървър

  34. Model View Dom Browser

  35. Model View Dom Browser

  36. Model View Dom Browser

  37. Model View Dom Browser

  38. Model View Dom Browser

  39. Model View Dom Browser

  40. Model View Dom Browser

  41. Model View Dom Browser

  42. Model View Dom Browser

  43. MV*

  44. Backbone.Events

  45. var object = {}; $.extend(object, Backbone.Events); object.on('eventName', function() { console.log('1');

    }); object.on('eventName', function() { console.log('2'); }); object.trigger('eventName'); // prints '1' and '2'
  46. var object = {}; $.extend(object, Backbone.Events); object.on('eventName', function() { console.log('1');

    }); object.on('eventName', function() { console.log('2'); }); object.trigger('eventName'); // prints '1' and '2'
  47. var object = {}; $.extend(object, Backbone.Events); object.on('eventName', function() { console.log('1');

    }); object.on('eventName', function() { console.log('2'); }); object.trigger('eventName'); // prints '1' and '2'
  48. var object = {}; $.extend(object, Backbone.Events); object.on('eventName', function() { console.log('1');

    }); object.on('eventName', function() { console.log('2'); }); object.trigger('eventName'); // prints '1' and '2'
  49. var object = {}; $.extend(object, Backbone.Events); object.on('eventName', function() { console.log('1');

    }); object.on('eventName', function() { console.log('2'); }); object.trigger('eventName'); // prints '1' and '2'
  50. Backbone.Model

  51. var Person = Backbone.Model.extend({ initialize: function() { console.log("I'm alive!"); }

    }); new Person();
  52. var Person = Backbone.Model.extend({ initialize: function() { console.log("I'm alive!"); }

    }); new Person();
  53. var Person = Backbone.Model.extend({ initialize: function() { console.log("I'm alive!"); }

    }); new Person();
  54. var Person = Backbone.Model.extend({}); var me = new Person({name: 'Radoslav'});

    me.get('name'); // Radoslav me.set({lastName: 'Stankov'}); me.set(lastName, 'Stankov'); me.get('lastName'); // Stankov
  55. var Person = Backbone.Model.extend({}); var me = new Person({name: 'Radoslav'});

    me.get('name'); // Radoslav me.set({lastName: 'Stankov'}); me.set(lastName, 'Stankov'); me.get('lastName'); // Stankov
  56. var Person = Backbone.Model.extend({}); var me = new Person({name: 'Radoslav'});

    me.get('name'); // Radoslav me.set({lastName: 'Stankov'}); me.set(lastName, 'Stankov'); me.get('lastName'); // Stankov
  57. var Person = Backbone.Model.extend({}); var me = new Person({name: 'Radoslav'});

    me.get('name'); // Radoslav me.set({lastName: 'Stankov'}); me.set(lastName, 'Stankov'); me.get('lastName'); // Stankov
  58. var Person = Backbone.Model.extend({}); var me = new Person({name: 'Radoslav'});

    me.get('name'); // Radoslav me.set({lastName: 'Stankov'}); me.set(lastName, 'Stankov'); me.get('lastName'); // Stankov
  59. var Person = Backbone.Model.extend({ defaults: { name: 'John', lastName: 'Doe',

    } }); var me = new Person(); me.get('name'); // John me.get('lastName'); // Doe
  60. var Person = Backbone.Model.extend({ defaults: { name: 'John', lastName: 'Doe',

    } }); var me = new Person(); me.get('name'); // John me.get('lastName'); // Doe
  61. var Person = Backbone.Model.extend({ defaults: { name: 'John', lastName: 'Doe',

    } }); var me = new Person(); me.get('name'); // John me.get('lastName'); // Doe
  62. var Person = Backbone.Model.extend({ defaults: { name: 'John', lastName: 'Doe',

    } }); var me = new Person(); me.get('name'); // John me.get('lastName'); // Doe
  63. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, value:

    function(){ return this.get('value'); }, sum: function(value){ this.set(value, value + this.get('value')); }, reset: function(){ this.set(value, 0); } });
  64. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, value:

    function(){ return this.get('value'); }, sum: function(value){ this.set(value, value + this.get('value')); }, reset: function(){ this.set(value, 0); } });
  65. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, value:

    function(){ return this.get('value'); }, sum: function(value){ this.set(value, value + this.get('value')); }, reset: function(){ this.set(value, 0); } });
  66. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, value:

    function(){ return this.get('value'); }, sum: function(value){ this.set(value, value + this.get('value')); }, reset: function(){ this.set(value, 0); } });
  67. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, value:

    function(){ return this.get('value'); }, sum: function(value){ this.set(value, value + this.get('value')); }, reset: function(){ this.set(value, 0); } });
  68. var cal = new Calculator(); cal.on('change:value', function(model, value){ console.log(value); });

    cal.on('change', function(model){ console.log(model.get('value')); }); cal.on('all', function(eventName) { console.log('I see everything!', eventName); });
  69. var cal = new Calculator(); cal.on('change:value', function(model, value){ console.log(value); });

    cal.on('change', function(model){ console.log(model.get('value')); }); cal.on('all', function(eventName) { console.log('I see everything!', eventName); });
  70. var cal = new Calculator(); cal.on('change:value', function(model, value){ console.log(value); });

    cal.on('change', function(model){ console.log(model.get('value')); }); cal.on('all', function(eventName) { console.log('I see everything!', eventName); });
  71. var cal = new Calculator(); cal.on('change:value', function(model, value){ console.log(value); });

    cal.on('change', function(model){ console.log(model.get('value')); }); cal.on('all', function(eventName) { console.log('I see everything!', eventName); });
  72. var cal = new Calculator(); cal.on('myEvent', function(){ console.log('KaBoom....'); }); cal.trigger('myEvent');

  73. var Product = Backbone.Model.extend({ urlRoot: '/products' }); var chair =

    new Product({ name: 'chair', price: 10 }); chair.save(); // POST /products
  74. var Product = Backbone.Model.extend({ url: function(){ return '/products/' + (this.isNew()

    ? '' : this.id); } }); var chair = new Product({ id: 5, name: 'chair', price: 10 }); chair.save(); // PUT /products/1
  75. http://backbonejs.org/#Model-save

  76. И още... • validate • escape • has • unset

    • clear • hasChanged • changedAttributes • previousAttributes • fetch • toJSON • clone
  77. Backbone.View

  78. None
  79. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  80. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  81. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  82. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  83. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  84. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  85. var UserNameView = Backbone.View.extend({ tagName: 'input', className: 'string optional', id:

    'user-name', attributes: { type: 'string', name: 'user[name]' } }); var userName = new UserNameView(); console.log(userName.el); <input type="string" name="user[name]" id="user-name" class="string optional">
  86. var UsersListView = Backbone.View.extend({ el: '#users-list' }); var userList =

    new UsersListView(); console.log(userList.el);
  87. var EditBoxView = Backbone.View.extend({}); var element = $('#edit-box-view').get(0), editBox =

    new EditBoxView({el: element}); console.log(editBox.el === element);
  88. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  89. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  90. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  91. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  92. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  93. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  94. var DocumentView = Backbone.View.extend({ events: { 'dblclick': 'open', 'click .grid

    .doc': 'select', 'customEvent .title': 'custom' }, open: function() {}, select: function() {}, custom: function() {} });
  95. <script type="text/template" id="news"> <h1><%= title %></h1> <time><%= created_at %></time> <p><%=

    text %></p> </script>
  96. var NewsView = Backbone.View.extend({ template: _.template($('#news').html()), render: function() { this.$el.html(this.template(this.model));

    return this; } });
  97. var NewsView = Backbone.View.extend({ template: _.template($('#news').html()), render: function() { this.$el.html(this.template(this.model));

    return this; } });
  98. var NewsView = Backbone.View.extend({ template: _.template($('#news').html()), render: function() { this.$el.html(this.template(this.model));

    return this; } });
  99. var view = new NewsView({ model: { title: "News Title",

    created_at: "Today", text: "Long text" } }); $(’body’).html(view.render().el);
  100. <script type="text/template" id="news"> <h1><%= title %></h1> <time><%= created_at %></time> <p><%=

    text %></p> </script>
  101. <div> <h1>News Title</h1> <time>Today</time> <p>Long text</p> </div>

  102. Model View DOM

  103. Model View DOM

  104. Model View DOM

  105. Model View DOM

  106. Model View DOM

  107. Model View DOM

  108. Model View DOM

  109. Model View DOM

  110. Model View DOM

  111. Model View DOM

  112. Model View DOM View 2

  113. Model View DOM View 2

  114. Model View DOM View 2

  115. Model View DOM View 2

  116. Model View DOM View 2

  117. Model View DOM View 2

  118. Model View DOM View 2

  119. Model View DOM View 2

  120. Model View DOM View 2

  121. Model View DOM View 2

  122. Model View DOM View 2

  123. Model View DOM View 2 View 3

  124. Model View DOM View 2 View 3 View 4

  125. Model View DOM View 2 View 3 View 4 View

    .. N
  126. Model View DOM View 2 View 3 View 4 View

    .. N
  127. Model View DOM View 2 View 3 View 4 View

    .. N
  128. Model View DOM View 2 View 3 View 4 View

    .. N
  129. Model View DOM View 2 View 3 View 4 View

    .. N
  130. Model View DOM View 2 View 3 View 4 View

    .. N
  131. Model View DOM View 2 View 3 View 4 View

    .. N
  132. Model View DOM View 2 View 3 View 4 View

    .. N
  133. Model View DOM View 2 View 3 View 4 View

    .. N
  134. Demo 1

  135. var Calculator = Backbone.Model.extend({ defaults: { value: 0 }, increment:

    function() { this.set('value', this.get('value') + 1); }, decrement: function() { this.set('value', this.get('value') - 1); }, getValue: function() { return this.get('value'); } });
  136. var ButtonsView = Backbone.View.extend({ events: { 'click .plus': 'plus', 'click

    .minus': 'minus' }, plus: function() { this.model.increment(); }, minus: function() { this.model.decrement(); } });
  137. var DisplayView = Backbone.View.extend({ initialize: function() { this.model.on('change:value', this.render, this);

    this.render(); }, render: function() { this.$el.html(this.model.getValue()); return this; } });
  138. var cal = new Calculator(); new ButtonsView({model: cal, el: '.buttons'});

    new DisplayView({model: cal, el: '.display'});
  139. Backbone.Collection

  140. var ProductsCollection = Backbone.Collection.extend({ model: Product }); var products =

    new ProductsCollection(); products.fetch(); products.on('reset', function(list) { console.log('Loaded', list.length, 'records'); });
  141. products.on('add', function(model) { console.log('new product added'); }); products.on('remove', function(model) {

    console.log('item product removed'); });
  142. И още... • Underscore Methods • add / remove /

    at • sort / comparator • reset • create • url • toJSON
  143. Backbone.Router

  144. None
  145. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  146. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  147. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  148. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  149. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  150. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  151. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  152. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  153. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  154. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  155. var AppRouter = Backbone.Router.extend({ routes: { 'pages': 'index', 'pages/search/:q': 'search',

    'pages/:id': 'show' }, initialize: function() { console.log('initialize'); }, index: function() { /* code */ }, search: function(query) { /* code */ }, show: function(id) { /* code */ } }); var app = new AppRouter(); Backbone.history.start();
  156. app.navigate('pages', {trigger: true}); app.navigate('pages/search/title', {trigger: true}); app.navigate('pages/3', {trigger: true});

  157. app.navigate('pages', {trigger: true}); app.navigate('pages/search/title', {trigger: true}); app.navigate('pages/3', {trigger: true});

  158. app.navigate('pages', {trigger: true}); app.navigate('pages/search/title', {trigger: true}); app.navigate('pages/3', {trigger: true});

  159. site.com/path#pages site.com/path#pages/search/title site.com/path#pages/3

  160. None
  161. Backbone.history.start({ pushState: true, root: '/path/' });

  162. site.com/path#pages site.com/path#pages/search/title site.com/path#pages/3

  163. site.com/path/pages site.com/path/pages/search/title site.com/path/pages/3

  164. Demo 2

  165. None
  166. None
  167. None
  168. None
  169. None
  170. None
  171. None
  172. None
  173. None
  174. Plugins https://github.com/RStankov/backbone-handlebars https://github.com/RStankov/backbone-bind-to https://github.com/n-time/backbone.validations https://github.com/PaulUithol/Backbone-relational https://github.com/thoughtbot/backbone-support

  175. Resources

  176. Resources http://backbonejs.org/

  177. Resources http://backbonejs.org/ https://workshops.thoughtbot.com/products/1-backbone-js-on-rails

  178. Resources http://backbonejs.org/ https://workshops.thoughtbot.com/products/1-backbone-js-on-rails http://recipeswithbackbone.com/

  179. Resources http://backbonejs.org/ https://workshops.thoughtbot.com/products/1-backbone-js-on-rails http://recipeswithbackbone.com/ https://github.com/addyosmani/backbone-fundamentals

  180. Problems

  181. Problems

  182. Problems Ghost views

  183. Problems Ghost views Plugin system

  184. Problems Ghost views Plugin system Template system

  185. Problems Ghost views Plugin system Template system Subviews

  186. Problems Ghost views Plugin system Template system Subviews Weak conventions

  187. Problems Ghost views Plugin system Template system Subviews Weak conventions

    Backbone.Application
  188. Alternatives

  189. Alternatives

  190. Alternatives

  191. Alternatives

  192. None
  193. https://github.com/RStankov/backbone-presentation Code & Slides:

  194. Questions?

  195. Thanks for listening :) @rstankov