Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

  • 2,365 views
Uploaded on

Presented at jQuery Conf Portland 2013

Presented at jQuery Conf Portland 2013

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
2,365
On Slideshare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
14
Comments
0
Likes
0

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 Stateful Modules with Events and PromisesDOMManipulationpatrickCAMACHOBeyondFriday, June 14, 13
  • 2. CrashlyticsforAndroid&iOSFriday, June 14, 13
  • 3. Friday, June 14, 13
  • 4. Friday, June 14, 13
  • 5. Friday, June 14, 13
  • 6. Friday, June 14, 13
  • 7. Railsto Backbone.Friday, June 14, 13
  • 8. Whatdidwehave?ModelBackbone.ModelBackbone.CollectionRoutingBackbone.Router,Backbone.HistoryViewsBackbone.ViewsEventsBackbone.EventsMV* componentsFriday, June 14, 13
  • 9. What’smissing?Friday, June 14, 13
  • 10. TransitioningPagestoStates.Friday, June 14, 13
  • 11. Piecemeal.AppStateFriday, June 14, 13
  • 12. Piecemeal.AppRouterStateFriday, June 14, 13
  • 13. Piecemeal.AppRouter DirectorsStateFriday, June 14, 13
  • 14. Piecemeal.AppRouter DirectorsStateFriday, June 14, 13
  • 15. Addingamodal.Friday, June 14, 13
  • 16. Friday, June 14, 13
  • 17. Neededbetterstructure.• Builtonsingleflowandstates• Modaldidn’tfitflow• BacktothedrawingboardAppRouter DirectorsStateFriday, June 14, 13
  • 18. Neededbetterstructure.• Builtonsingleflowandstates• Modaldidn’tfitflow• BacktothedrawingboardAppRouter DirectorsStateSettingsFriday, June 14, 13
  • 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. Asyncbehavior.Friday, June 14, 13
  • 21. Asyncbehaviorinstates.• Fetchingdata,animations,etc• WanttoshutanythingdownwhenstoppingSettingsServer(rendering)Friday, June 14, 13
  • 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. 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. Goodintheshortrun.• Onlyhadoneapplication• Componentslivedforever• SingletonshidtheproblemsSettings Alert CenterRealTime AnalyticsFriday, June 14, 13
  • 25. Multipleapplications.Friday, June 14, 13
  • 26. Distinctfunctionality.Friday, June 14, 13
  • 27. Distinctfunctionality.Friday, June 14, 13
  • 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. Multipleapplications.AppsRouter DirectorsStateFriday, June 14, 13
  • 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. Findingapattern.Friday, June 14, 13
  • 32. Sameproblem,differentlevels.• Eventing• Start• Stop• DependenciesAppState StateComponent Component ComponentFriday, June 14, 13
  • 33. Isolatingknowledge.Friday, June 14, 13
  • 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. 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. • Wantedevents,butnottheknowledgeStilltightlycoupled.Dashboard.start = function() {Onboarding.trigger(stop, this.dependencies);LoggedOut.trigger(stop, this.dependencies);}Friday, June 14, 13
  • 37. Simplifyfunctionality.Friday, June 14, 13
  • 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. 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. 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. Sharinginformation.Friday, June 14, 13
  • 42. • Sharedatabetweenmodules• UseventtoregisterresponsesandrequestSynchronousdatareturns.VentDashboard SettingsFriday, June 14, 13
  • 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. Tyingitalltogether.Friday, June 14, 13
  • 45. Modularizeallthethings!• Isolatedfunctionality• Start/stop• Managingdependencies• Eventing• AsyncbehaviorFriday, June 14, 13
  • 46. Modularizeallthethings!ComponentAppState• Isolatedfunctionality• Start/stop• Managingdependencies• Eventing• AsyncbehaviorFriday, June 14, 13
  • 47. VentRethinkingtheflow.Friday, June 14, 13
  • 48. VentRethinkingtheflow.RouterFriday, June 14, 13
  • 49. ComponentsVentRethinkingtheflow.AppsRouterFriday, June 14, 13
  • 50. VentComponentsVentRethinkingtheflow.AppsRouterStatesFriday, June 14, 13
  • 51. VentVentComponentsVentRethinkingtheflow.AppsRouterStatesStatesFriday, June 14, 13
  • 52. Makingityours• Managecomplexityandscale• Isolatefunctionalityintomodules• Managedependencies• AllowmodulestocommunicatethroughaventFriday, June 14, 13
  • 53. YOUpatrickCAMACHOThanktry.crashlytics.com/jobsFriday, June 14, 13