Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

5,005 views
4,829 views

Published on

Presented at jQuery Conf Portland 2013

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
5,005
On SlideShare
0
From Embeds
0
Number of Embeds
123
Actions
Shares
0
Downloads
19
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

  1. 1. Building Stateful Modules with Events and PromisesDOMManipulationpatrickCAMACHOBeyondFriday, June 14, 13
  2. 2. CrashlyticsforAndroid&iOSFriday, June 14, 13
  3. 3. Friday, June 14, 13
  4. 4. Friday, June 14, 13
  5. 5. Friday, June 14, 13
  6. 6. Friday, June 14, 13
  7. 7. Railsto Backbone.Friday, June 14, 13
  8. 8. Whatdidwehave?ModelBackbone.ModelBackbone.CollectionRoutingBackbone.Router,Backbone.HistoryViewsBackbone.ViewsEventsBackbone.EventsMV* componentsFriday, June 14, 13
  9. 9. What’smissing?Friday, June 14, 13
  10. 10. TransitioningPagestoStates.Friday, June 14, 13
  11. 11. Piecemeal.AppStateFriday, June 14, 13
  12. 12. Piecemeal.AppRouterStateFriday, June 14, 13
  13. 13. Piecemeal.AppRouter DirectorsStateFriday, June 14, 13
  14. 14. Piecemeal.AppRouter DirectorsStateFriday, June 14, 13
  15. 15. Addingamodal.Friday, June 14, 13
  16. 16. Friday, June 14, 13
  17. 17. Neededbetterstructure.• Builtonsingleflowandstates• Modaldidn’tfitflow• BacktothedrawingboardAppRouter DirectorsStateFriday, June 14, 13
  18. 18. Neededbetterstructure.• Builtonsingleflowandstates• Modaldidn’tfitflow• BacktothedrawingboardAppRouter DirectorsStateSettingsFriday, June 14, 13
  19. 19. Thebirthofthe“module”.• Entirelyindependentpiecesoffunctionality• Itcouldaccepteventsandstart/stopitselfStatethis.$(.settings).click(function(){CLS.Components.Settings.trigger(start);});Settingsthis.$(.overlay).click((function(){this.trigger(stop);}).bind(this));Friday, June 14, 13
  20. 20. Asyncbehavior.Friday, June 14, 13
  21. 21. Asyncbehaviorinstates.• Fetchingdata,animations,etc• WanttoshutanythingdownwhenstoppingSettingsServer(rendering)Friday, June 14, 13
  22. 22. Promises.• $.Promisesand$.Deferreds• .done,.fail,.always• .resolve,.rejectfetch1 = $.get(data.json);fetch2 = $.get(data2.json);fetch1.done(function(){ console.log(‘success!’); }fetch2.always(function(){ console.log(‘complete!’); }$.when(fetch1, fetch2).fail(function(){console.log(‘fail!’);});Friday, June 14, 13
  23. 23. UsingwithComponents.Settings.start = function() {this.stopDeferred = $.Deferred();fetch1 = $.get(data.json);this.stopDeferred.done(fetch1.abort);fetch2 = $.get(data2.json);this.stopDeferred.done(fetch2.abort);$.when(fetch1, fetch2).done(this.render.bind(this));}Settings.stop = function() {this.stopDeferred.resolve();}Friday, June 14, 13
  24. 24. Goodintheshortrun.• Onlyhadoneapplication• Componentslivedforever• SingletonshidtheproblemsSettings Alert CenterRealTime AnalyticsFriday, June 14, 13
  25. 25. Multipleapplications.Friday, June 14, 13
  26. 26. Distinctfunctionality.Friday, June 14, 13
  27. 27. Distinctfunctionality.Friday, June 14, 13
  28. 28. Multipleapplications.• Lostcoreassumptionofapage-longapp• AppsbegantolookmoreandmorelikemodulesOnboardingOnboarding.start : function(){if(this._isActive) return;...this._isActive = true;}Onboarding.stop : function(){if(!this._isActive) return;...this._isActive = false;}Friday, June 14, 13
  29. 29. Multipleapplications.AppsRouter DirectorsStateFriday, June 14, 13
  30. 30. Persistentfunctionalty.• Componentsneededtobestarted/stoppedbyappsonstart/stop• Notallshouldbestartedorstopped• Backtoheavyconditionalsif(nextApp === onboard) {CLS.Components.Settings.trigger(stop);CLS.Components.AlertCenter.trigger(stop);} else if(nextApp === logout) {CLS.Components.Settings.trigger(stop);CLS.Components.AlertCenter.trigger(stop);CLS.Components.RealTime.trigger(stop);} else if...Friday, June 14, 13
  31. 31. Findingapattern.Friday, June 14, 13
  32. 32. Sameproblem,differentlevels.• Eventing• Start• Stop• DependenciesAppState StateComponent Component ComponentFriday, June 14, 13
  33. 33. Isolatingknowledge.Friday, June 14, 13
  34. 34. Toomanydirectreferences.• Don’tknowoutsideinformation• Clearestinstoppingdependenciesif(nextApp === onboard) {CLS.Components.Settings.trigger(stop);CLS.Components.AlertCenter.trigger(stop);} else if(nextApp === logout) {CLS.Components.Settings.trigger(stop);CLS.Components.AlertCenter.trigger(stop);CLS.Components.RealTime.trigger(stop);} else if...Friday, June 14, 13
  35. 35. Eventingwitharguments.Onboarding DashboardDashboard.start = function() {Onboarding.trigger(stop, this.dependencies);}Onboarding.stop = function(dependencies) {if(dependencies == null) { dependencies = [] }this.dependencies.forEach(function(dependencies){if(dependencies.indexOf(dependency) < 0) {dependency.trigger(stop, dependencies);}});}Friday, June 14, 13
  36. 36. • Wantedevents,butnottheknowledgeStilltightlycoupled.Dashboard.start = function() {Onboarding.trigger(stop, this.dependencies);LoggedOut.trigger(stop, this.dependencies);}Friday, June 14, 13
  37. 37. Simplifyfunctionality.Friday, June 14, 13
  38. 38. Usingavent.• Allofthesepiecesareusingevents• IsolatethatfunctionalitytoasingleunitVentVent = function() {...}Vent.prototype.on = function() {...}Vent.prototype.one = function() {...}Vent.prototype.off = function() {...}Vent.prototype.trigger = function() {...}Friday, June 14, 13
  39. 39. Sharingavent.OnboardingDashboard VentOnboarding.start = function() {this.vent.trigger(app:dashboard:stop, this.dependencies);this.vent.trigger(app:loggedOut:stop, this.dependencies);}Friday, June 14, 13
  40. 40. Smartsubscriptions.Dashboard.start = function(vent) {this.vent.trigger(app:onBeforeStart, this.dependencies);this.vent.one(app:onBeforeStart, this.stop.bind(this));}Onboarding.start = function(vent) {this.vent.trigger(app:onBeforeStart, this.dependencies);this.vent.one(app:onBeforeStart, this.stop.bind(this));}OnboardingDashboard VentFriday, June 14, 13
  41. 41. Sharinginformation.Friday, June 14, 13
  42. 42. • Sharedatabetweenmodules• UseventtoregisterresponsesandrequestSynchronousdatareturns.VentDashboard SettingsFriday, June 14, 13
  43. 43. Dashboard.start = function() {this.currentApplication = ‘foo bar’this.vent.setResponse(current_application,(function(){ return this.currentApplication; }).bind(this););}Settings.start = function() {app = this.vent.requestResponse(current_application);}Synchronousdatareturns.Friday, June 14, 13
  44. 44. Tyingitalltogether.Friday, June 14, 13
  45. 45. Modularizeallthethings!• Isolatedfunctionality• Start/stop• Managingdependencies• Eventing• AsyncbehaviorFriday, June 14, 13
  46. 46. Modularizeallthethings!ComponentAppState• Isolatedfunctionality• Start/stop• Managingdependencies• Eventing• AsyncbehaviorFriday, June 14, 13
  47. 47. VentRethinkingtheflow.Friday, June 14, 13
  48. 48. VentRethinkingtheflow.RouterFriday, June 14, 13
  49. 49. ComponentsVentRethinkingtheflow.AppsRouterFriday, June 14, 13
  50. 50. VentComponentsVentRethinkingtheflow.AppsRouterStatesFriday, June 14, 13
  51. 51. VentVentComponentsVentRethinkingtheflow.AppsRouterStatesStatesFriday, June 14, 13
  52. 52. Makingityours• Managecomplexityandscale• Isolatefunctionalityintomodules• Managedependencies• AllowmodulestocommunicatethroughaventFriday, June 14, 13
  53. 53. YOUpatrickCAMACHOThanktry.crashlytics.com/jobsFriday, June 14, 13

×