Your SlideShare is downloading. ×

Building Evented Single Page Applications

4,356

Published on

Published in: Technology, Sports
1 Comment
20 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,356
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
197
Comments
1
Likes
20
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. building evented single-page applications Sunday, September 13, 2009
  • 2. 1. who 2. why 3. demo 4. how Sunday, September 13, 2009
  • 3. 1. who Sunday, September 13, 2009
  • 4. chancellor http://orderedlist.com/ Sunday, September 13, 2009
  • 5. professor http://teaching.johnnunemaker.com/ Sunday, September 13, 2009
  • 6. rubyist http://railstips.org/ Sunday, September 13, 2009
  • 7. i’m not perfect Sunday, September 13, 2009
  • 8. 2. why Sunday, September 13, 2009
  • 9. because? Sunday, September 13, 2009
  • 10. because? Sunday, September 13, 2009
  • 11. speed only send what changes across the wire Sunday, September 13, 2009
  • 12. perceived speed Sunday, September 13, 2009
  • 13. interactivity Sunday, September 13, 2009
  • 14. but the greatest of these is... experience Sunday, September 13, 2009
  • 15. 3. demo Sunday, September 13, 2009
  • 16. http://peoplebase.com/ http://harmonyapp.com/ Sunday, September 13, 2009
  • 17. 4. how Sunday, September 13, 2009
  • 18. goals Sunday, September 13, 2009
  • 19. no reloads Sunday, September 13, 2009
  • 20. no reloads history/refresh Sunday, September 13, 2009
  • 21. no reloads history/refresh easy Sunday, September 13, 2009
  • 22. # Sunday, September 13, 2009
  • 23. no reloads history/refresh easy Sunday, September 13, 2009
  • 24. no reloads history/refresh easy Sunday, September 13, 2009
  • 25. no reloads history/refresh easy Sunday, September 13, 2009
  • 26. no reloads history/refresh easy Sunday, September 13, 2009
  • 27. the end Sunday, September 13, 2009
  • 28. no reloads Sunday, September 13, 2009
  • 29. <a href="#/items">Items</a> Sunday, September 13, 2009
  • 30. $("a[href^='#/']").live('click', function (event) { var $link = $(this); window.location.hash = $link.attr('href'); $(document).trigger('hashchange'); return false; }); Sunday, September 13, 2009
  • 31. $(document).bind('hashchange', Layout.reload); Sunday, September 13, 2009
  • 32. var Layout = { reload: function() { Layout.load(window.location.hash); } }; Sunday, September 13, 2009
  • 33. var Layout = { load: function(path, options) { path = path.replace(/^#/, ''); // trigger path loading events $.ajax({ url : path, dataType : 'json', success : function(json) { Layout.onSuccess(json); // trigger path success events if (options && options.success) { options.success(); } }, complete : function() { if (options && options.complete) { options.complete(); } } }); } }; Sunday, September 13, 2009
  • 34. var Layout = { load: function(path, options) { path = path.replace(/^#/, ''); $(document).trigger('path:loading', [path]); $(document).trigger('path:loading:' + path); $.ajax({ url: path, dataType: 'json', success: function(json) { Layout.onSuccess(json); $(document).trigger('path:success', [path, json]); $(document).trigger('path:success:' + path, [json]); if (options && options.success) { options.success(); } }, complete: function() { if (options && options.complete) { options.complete(); } } }); } }; Sunday, September 13, 2009
  • 35. var Layout = { onSuccess: function(json) { Layout.applyJSON(json); // trigger layout success }, }; Sunday, September 13, 2009
  • 36. no reloads Sunday, September 13, 2009
  • 37. history/refresh Sunday, September 13, 2009
  • 38. setInterval(function() { var hash_is_new = window.location.hash && window.currentHash != window.location.hash; if (hash_is_new) { window.currentHash = window.location.hash; Layout.handlePageLoad(); } }, 300); Sunday, September 13, 2009
  • 39. #/org/groups/12/45/new Sunday, September 13, 2009
  • 40. org groups 12 45 new Sunday, September 13, 2009
  • 41. org groups 12 45 new Sunday, September 13, 2009
  • 42. org groups 12 45 new Sunday, September 13, 2009
  • 43. org groups 12 45 new Sunday, September 13, 2009
  • 44. org groups 12 45 new Sunday, September 13, 2009
  • 45. org groups 12 45 new Sunday, September 13, 2009
  • 46. var Layout = { handlePageLoad: function() { var segments = window.location.hash.replace(/^#//, '').split('/'), total = segments.length, path = ''; function loadSectionsInOrder() { var segment = segments.shift(); path += '/' + segment; var onComplete = function() { var loaded = total - segments.length, finished = loaded == total; if (!finished) { loadSectionsInOrder(); } }; Layout.load(path, {complete: onComplete}); } loadSectionsInOrder(); } }; Sunday, September 13, 2009
  • 47. var Layout = { handlePageLoad: function() { var segments = window.location.hash.replace(/^#//, '').split('/'), total = segments.length, path = ''; $(document).trigger('page:loading'); function loadSectionsInOrder() { var segment = segments.shift(); path += '/' + segment; var onComplete = function() { var loaded = total - segments.length, finished = loaded == total; $(document).trigger('page:progress', [total, loaded]); if (finished) { $(document).trigger('page:loaded'); } else { loadSectionsInOrder(); } }; Layout.load(path, {complete: onComplete}); } loadSectionsInOrder(); } }; Sunday, September 13, 2009
  • 48. $(document).bind('page:progress', function(e, total, loaded) { if (total != loaded) { var final_width = 114, new_width = (loaded/total) * final_width; $('#loading_progress').animate({width: new_width+'px'}, 200); } }); $(document).bind('page:loading', function() { $('#harmony_loading').show(); $('#loading_progress').css('width', 0); }); $(document).bind('page:loaded', function() { $('#loading_progress').animate({width:'114px'}, 300, 'linear', function() { $('#harmony_loading').hide(); }); }); Sunday, September 13, 2009
  • 49. history/refresh Sunday, September 13, 2009
  • 50. easy Sunday, September 13, 2009
  • 51. rule #1: abuse events for better code separation and easier customization http://orderedlist.com/articles/jquery-evented-programming-primer Sunday, September 13, 2009
  • 52. $('form').live('submit', function(event) { var $form = $(this); $form.ajaxSubmit({ dataType: 'json', beforeSend: function() { // trigger before send }, success: function(json) { // if errors, show them, else apply json and reset form }, error: function(response, status, error) { // trigger error }, complete: function() { // trigger complete } }); return false; }); Sunday, September 13, 2009
  • 53. $('form').live('submit', function(event) { var $form = $(this); $form.ajaxSubmit({ dataType: 'json', beforeSend: function() { $form.trigger('form:beforeSend'); }, success: function(json) { if (json.errors) { $form.showErrors(json.errors); } else { Layout.onSuccess(json); $form.trigger('form:success', [json]); $form.resetForm(); } }, error: function(response, status, error) { $form.trigger('form:error', [response, status, error]); }, complete: function() { $form.trigger('form:complete'); } }); return false; }); Sunday, September 13, 2009
  • 54. var Site = { onCreateSuccess: function(event, json) { Sidebar.highlight($('#site_' + json.id)) Layout.updateHashWithoutLoad(window.location.hash.replace(/new$/, json.id)); }, onUpdateSuccess: function(event, json) { Sidebar.highlight($('#site_' + json.id)) } }; $('form.new_site').live('form:success', Site.onCreateSuccess); $('form.edit_site').live('form:success', Site.onUpdateSuccess); Sunday, September 13, 2009
  • 55. var Field = { onCreateSuccess: function(event, json) { $('#list_section_' + json.section_id) .addSectionField(json.field_title.toLowerCase()); }, onUpdateSuccess: function(event, json) { $('#list_section_' + json.section_id) .removeSectionField(json.old_title.toLowerCase()) .addSectionField(json.new_title.toLowerCase()); } }; $('form.new_field') .live('form:success', Field.onCreateSuccess); $('form.edit_field').live('form:success', Field.onUpdateSuccess); Sunday, September 13, 2009
  • 56. Layout.applyJSON accepts json like below and “applies” it to the layout; gets called with each url load either from click or form Sunday, September 13, 2009
  • 57. Layout.applyJSON { 'replace': { '#content': '<h1>Heading</h1><p>Yay!</p>' }, 'replaceWith': { '#post_12': '<div class="post">...</div>' }, 'remove': ['#post_11', '#comment_12'] } Sunday, September 13, 2009
  • 58. rule #2: the url dictates everything Sunday, September 13, 2009
  • 59. var Layout = { livePath: function(event, path, callback) { if (typeof(test) === 'string') { $(document).bind('path:' + event + ':' + path, callback); } else { Layout.live_path_regex[event].push([path, callback]); } } }; Sunday, September 13, 2009
  • 60. Layout.livePath('loading', //org/([^/]+)([0-9/]+).*/, Groups.loading); Layout.livePath('loading', //sections/([0-9]+)$/, Sections.markCurrent); Layout.livePath('success', '/org/groups', Groups.setup); Layout.livePath('success', '/sections', Sections.makeSortable); Layout.livePath('success', //admin/assets(.*)/, Assets.init); Layout.livePath('success', //admin/items/(d+)/, ItemForm.init); Layout.livePath('success', //admin/items/([0-9/]+)/, Items.manageSidebar); Sunday, September 13, 2009
  • 61. rule #3: do it live Sunday, September 13, 2009
  • 62. $('a.field_form_toggler') .live('click', Fields.toggleAddFieldForm); $('form.new_section') .live('form:success', SectionForm.onCreateSuccess); $('form.edit_section') .live('form:success', SectionForm.onUpdateSuccess); $('form.new_field') .live('form:success', Field.onCreateSuccess); $('form.edit_field') .live('form:success', Field.onUpdateSuccess); $('a.field_destroy') .live('destroy:success', Field.onDestroySuccess); Sunday, September 13, 2009
  • 63. easy Sunday, September 13, 2009

×