53
Building Stateful Modules with Events and Promises DOM Manipulation patrick CAMACHO Beyond Friday, June 14, 13

Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Embed Size (px)

DESCRIPTION

Presented at jQuery Conf Portland 2013

Citation preview

Page 1: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Building Stateful Modules with Events and PromisesDOM Manipulation

patrickCAMACHO

Beyond

Friday, June 14, 13

Page 2: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Crashlytics for Android & iOS

Friday, June 14, 13

Page 3: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Friday, June 14, 13

Page 4: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Friday, June 14, 13

Page 5: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Friday, June 14, 13

Page 6: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Friday, June 14, 13

Page 7: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Rails to Backbone.

Friday, June 14, 13

Page 8: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

What did we have?

ModelBackbone.Model

Backbone.Collection

RoutingBackbone.Router,Backbone.History

ViewsBackbone.Views

EventsBackbone.Events

MV* components

Friday, June 14, 13

Page 9: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

What’s missing?

Friday, June 14, 13

Page 10: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Transitioning Pages to States.

Friday, June 14, 13

Page 11: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Piecemeal.

App

State

Friday, June 14, 13

Page 12: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Piecemeal.

App

Router

State

Friday, June 14, 13

Page 13: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Piecemeal.

App

Router Directors

State

Friday, June 14, 13

Page 14: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Piecemeal.

App

Router Directors

State

Friday, June 14, 13

Page 15: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Adding a modal.

Friday, June 14, 13

Page 16: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Friday, June 14, 13

Page 17: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Needed better structure.

• Built on single flow and

states

• Modal didn’t fit flow

• Back to the

drawing board

App

Router Directors

State

Friday, June 14, 13

Page 18: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Needed better structure.

• Built on single flow and

states

• Modal didn’t fit flow

• Back to the

drawing board

App

Router Directors

State

Settings

Friday, June 14, 13

Page 19: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

The birth of the “module”.

• Entirely independent pieces of functionality

• It could accept events and start / stop itself

State

this.$('.settings').click(function(){ CLS.Components.Settings.trigger('start');});

Settings

this.$('.overlay').click((function(){ this.trigger('stop');}).bind(this));

Friday, June 14, 13

Page 20: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Async behavior.

Friday, June 14, 13

Page 21: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Async behavior in states.

• Fetching data, animations, etc

• Want to shut anything down when stopping

Settings

Server

(rendering)

Friday, June 14, 13

Page 22: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Promises.

• $.Promises and $.Deferreds

• .done, .fail, .always

• .resolve, .reject

fetch1 = $.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

Page 23: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Using with Components.

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

Page 24: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Good in the short run.

• Only had one application

• Components lived

forever

• Singletons hid the

problems

Settings Alert Center

Real Time Analytics

Friday, June 14, 13

Page 25: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Multiple applications.

Friday, June 14, 13

Page 26: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Distinct functionality.

Friday, June 14, 13

Page 27: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Distinct functionality.

Friday, June 14, 13

Page 28: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Multiple applications.

• Lost core assumption of a page-long app

• Apps began to look more and more like modules

Onboarding

Onboarding.start : function(){ if(this._isActive) return; ... this._isActive = true;}

Onboarding.stop : function(){ if(!this._isActive) return; ... this._isActive = false;}

Friday, June 14, 13

Page 29: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Multiple applications.

Apps

Router Directors

State

Friday, June 14, 13

Page 30: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Persistent functionalty.

• Components needed to be started / stopped by apps on

start / stop

• Not all should be started or stopped

• Back to heavy conditionals

if(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

Page 31: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Finding a pattern.

Friday, June 14, 13

Page 32: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Same problem, different levels.

• Eventing

• Start

• Stop

• Dependencies

App

State State

Component Component Component

Friday, June 14, 13

Page 33: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Isolating knowledge.

Friday, June 14, 13

Page 34: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Too many direct references.

• Don’t know outside information

• Clearest in stopping dependencies

if(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

Page 35: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Eventing with arguments.

Onboarding Dashboard

Dashboard.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

Page 36: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

• Wanted events, but not the knowledge

Still tightly coupled.

Dashboard.start = function() { Onboarding.trigger('stop', this.dependencies); LoggedOut.trigger('stop', this.dependencies);}

Friday, June 14, 13

Page 37: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Simplify functionality.

Friday, June 14, 13

Page 38: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Using a vent.

• All of these pieces are using events

• Isolate that functionality to a single unit

Vent

Vent = function() {...}Vent.prototype.on = function() {...}Vent.prototype.one = function() {...}Vent.prototype.off = function() {...}Vent.prototype.trigger = function() {...}

Friday, June 14, 13

Page 39: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Sharing a vent.

OnboardingDashboard Vent

Onboarding.start = function() { this.vent.trigger('app:dashboard:stop', this.dependencies); this.vent.trigger('app:loggedOut:stop', this.dependencies);}

Friday, June 14, 13

Page 40: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Smart subscriptions.

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 Vent

Friday, June 14, 13

Page 41: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Sharing information.

Friday, June 14, 13

Page 42: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

• Share data between modules

• Use vent to register responses and request

Synchronous data returns.

VentDashboard Settings

Friday, June 14, 13

Page 43: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

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');}

Synchronous data returns.

Friday, June 14, 13

Page 44: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Tying it all together.

Friday, June 14, 13

Page 45: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Modularize all the things!

• Isolated functionality

• Start / stop

• Managing dependencies

• Eventing

• Async behavior

Friday, June 14, 13

Page 46: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Modularize all the things!

Component

App

State

• Isolated functionality

• Start / stop

• Managing dependencies

• Eventing

• Async behavior

Friday, June 14, 13

Page 47: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Vent

Rethinking the flow.

Friday, June 14, 13

Page 48: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Vent

Rethinking the flow.

Router

Friday, June 14, 13

Page 49: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

ComponentsVent

Rethinking the flow.

Apps

Router

Friday, June 14, 13

Page 50: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Vent

ComponentsVent

Rethinking the flow.

Apps

Router

States

Friday, June 14, 13

Page 51: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Vent

Vent

ComponentsVent

Rethinking the flow.

Apps

Router

States

States

Friday, June 14, 13

Page 52: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

Making it yours

• Manage complexity and scale

• Isolate functionality into modules

• Manage dependencies

• Allow modules to communicate through a vent

Friday, June 14, 13

Page 53: Beyond DOM Manipulations: Building Stateful Modules with Events and Promises

YOUpatrickCAMACHO

Thank

try.crashlytics.com/jobs

Friday, June 14, 13