applications: a series of states

230
applications: a series of states a talk by @trek

Upload: trek-glowacki

Post on 01-Dec-2014

408 views

Category:

Technology


0 download

DESCRIPTION

Chicago Ember.js Meetup, December 2012

TRANSCRIPT

Page 1: Applications: A Series of States

applications: a series of statesa talk by @trek

Page 2: Applications: A Series of States
Page 3: Applications: A Series of States
Page 4: Applications: A Series of States
Page 5: Applications: A Series of States
Page 6: Applications: A Series of States
Page 7: Applications: A Series of States

<a href=”serialize/user/intent.fmt”>

Page 8: Applications: A Series of States
Page 9: Applications: A Series of States
Page 10: Applications: A Series of States
Page 11: Applications: A Series of States
Page 12: Applications: A Series of States
Page 13: Applications: A Series of States
Page 14: Applications: A Series of States
Page 15: Applications: A Series of States
Page 16: Applications: A Series of States
Page 17: Applications: A Series of States
Page 18: Applications: A Series of States
Page 19: Applications: A Series of States
Page 20: Applications: A Series of States
Page 21: Applications: A Series of States
Page 22: Applications: A Series of States
Page 23: Applications: A Series of States
Page 24: Applications: A Series of States
Page 25: Applications: A Series of States
Page 26: Applications: A Series of States

GET https://simple.com/activity

Page 27: Applications: A Series of States
Page 28: Applications: A Series of States
Page 29: Applications: A Series of States

GET https://simple.com/activity/transactions/3a709ef6-c300-43b4-bca0-af72d1ecd4ba

Page 30: Applications: A Series of States
Page 31: Applications: A Series of States
Page 32: Applications: A Series of States
Page 33: Applications: A Series of States

GET https://simple.com/activity/transactions/3a709ef6-c300-43b4-bca0-af72d1ecd4ba/edit

Page 34: Applications: A Series of States
Page 35: Applications: A Series of States
Page 36: Applications: A Series of States
Page 37: Applications: A Series of States

PUT https://simple.com/activity/transactions/3a709ef6-c300-43b4-bca0-af72d1ecd4ba

HTTP 302 Found

GET https://simple.com/activity

Page 38: Applications: A Series of States
Page 39: Applications: A Series of States
Page 40: Applications: A Series of States

ͿԤԥԦԧԨԩԪԫԬԭԮԯՠֈ֍֎֏ࢪࢩࢨࢧࢦࢥࢤࢣࢢࢡࢠࡪࡩࡨࡧࡦࡥࡤࡣࡢࡡࡠ࡞࡛࡚࡙ࡘࡗࡖࡕࡔࡓࡒࡑࡐࡏࡎࡍࡌࡋࡊࡉࡈࡇࡆࡅࡄࡃࡂࡁࡀ࠾࠽࠼࠻࠺࠹࠸࠷࠶࠵࠴࠳࠲࠱࠰࠭ࠬࠫࠪࠩࠨࠧࠦࠥࠤࠣࠢࠡࠠࠟࠞࠝࠜࠛࠚ࠙࠘ࠗࠖࠕࠔࠓࠒࠑࠐࠏࠎࠍࠌࠋࠊࠉࠈࠇࠆࠅࠄࠃࠂࠁࠀ߿߾߽ٟؠׯ

Page 41: Applications: A Series of States
Page 42: Applications: A Series of States
Page 44: Applications: A Series of States
Page 45: Applications: A Series of States
Page 46: Applications: A Series of States

GET https://simple.com/activity

Page 47: Applications: A Series of States
Page 48: Applications: A Series of States
Page 49: Applications: A Series of States

$('.some-selector').click(function(){ $.ajax({ success: function(response){ var html = $templates.transactionDetails(response); $('#some-section-of-my-page).html(html); } })})

Page 50: Applications: A Series of States
Page 51: Applications: A Series of States
Page 52: Applications: A Series of States
Page 53: Applications: A Series of States

$('.some-selector').click(function(){ $.ajax({ success: function(response){ var html = $templates.transactionDetails(response); $('#some-section-of-my-page).html(html); } })})

Page 54: Applications: A Series of States
Page 55: Applications: A Series of States
Page 56: Applications: A Series of States
Page 57: Applications: A Series of States

$('.some-button').click(function(){ $.ajax({ type: ‘post’, success: function(response){ var html = $templates.transactionDetails(response); $('#some-section-of-my-page).html(html); } })})

Page 58: Applications: A Series of States
Page 59: Applications: A Series of States
Page 60: Applications: A Series of States

decent, not great.

Page 61: Applications: A Series of States

{}

Page 62: Applications: A Series of States

truth-in-dom

JSON, js, html

JSON, js, html

Page 63: Applications: A Series of States

{ vendor: 'Wholefds Kbs', amount: '20.70', isCredit: false, isPending: true, type: 'Groceries', location: { lat: '41.910006', long: '87.657166', address: '1070 N North Branch St,\n Chicago IL 60642' }}

Page 64: Applications: A Series of States

success: function(purchase){ var sidebar = $('#more-info'); if(purchase.isPending) { $('.is-pending', sidebar).show(); } $('.name', sidebar).html(purchase.vendor); $('.amount', sidebar).html('-' + purchase.amount); $('.category', sidebar).html(purchase.type); $('.map', sidebar).gMapPlugin(purchase.location); $('.address', sidebar).html(purchase.location.address);}

Page 65: Applications: A Series of States

success: function(purchase){ var sidebar = $('#more-info'), template = Templates.purchase; sidebar.html(template(purchase)); $('.map', sidebar).gMapPlugin(purchase.location);}

Page 66: Applications: A Series of States

truth-in-dom

JSON, js, html

JSON, js, html

Page 67: Applications: A Series of States

truth-in-dom

JSON, js, html

truth-in-domJSON, js,

html

truth-in-dom

Page 68: Applications: A Series of States
Page 69: Applications: A Series of States
Page 70: Applications: A Series of States
Page 71: Applications: A Series of States

success: function(purchase){ var sidebar = $('#more-info'), listItem = $(‘#list .purchase-’ + purchase.id), purchaseTemplate = Templates.purchase.show, purchaseTableRowTemplate = Templates.purchase.row; sidebar.html(purchaseTemplate(purchase)); listItem.html(purchaseTableRowTemplate(purchase)); $('.map', sidebar).gMapPlugin(purchase.location);}

Page 72: Applications: A Series of States
Page 73: Applications: A Series of States
Page 74: Applications: A Series of States
Page 75: Applications: A Series of States

<div id=”purchase-list”></div>

Page 76: Applications: A Series of States

View

Page 77: Applications: A Series of States

Collection of Models

Page 78: Applications: A Series of States

View

View

View

View

View

View

View

Page 79: Applications: A Series of States

Properties of the collection

Page 80: Applications: A Series of States

<div id=”details”></div>

Page 81: Applications: A Series of States

View

Page 82: Applications: A Series of States

Aggregation of Collection

Page 83: Applications: A Series of States

Different View

Page 84: Applications: A Series of States

Single Model

Page 85: Applications: A Series of States

GET https://simple.com/activity

Page 86: Applications: A Series of States
Page 87: Applications: A Series of States

app.Purchase = Backbone.Model.extend();

app.PurchaseList = Backbone.Collection.extend({ model: app.Purchase});app.PurchaseList.url = ‘purchases’

app.Purchases = new app.PurchaseList;

Page 88: Applications: A Series of States

app.PurchaseListView = Backbone.View.extend({el: ‘#purchase-list’,

initialize: function(){ this.collection = app.Purchases; this.collection.on('change', this.render, this) this.render(); }, render: function(){

this.$el.append(new PurchasesFilterView().render()); _.each(this.collection.models, function (item) { this.$el.append(new PurchaseRowView({model: item})

.render()); }, this); }});

Page 89: Applications: A Series of States

app.PurchaseRowView = Backbone.View.extend({ initialize: function() { this.model.on( 'change', this.render, this ); }, tagName: 'li', template: ..., events: {

'click': 'toggleMoreDetails', 'click .edit': 'toggleEdit'},

toggleMoreDetails: function(){ this.model.toggleMoreDetails(); this.$el.toggleClass( 'selected', this.moreDetailsShowing); }, render: function(){ this.$el.html(this.template(this.model)) }});

Page 90: Applications: A Series of States

app.PurchaseDetailsView = Backbone.View.extend({el: ‘#details’,

initialize: function(){ this.render(); }, template: '...', render: function(){

this.$el.html(this.template(this.model); }});

Page 91: Applications: A Series of States

app.Purchases.fetch();

Page 92: Applications: A Series of States

<div id=”purchase-list”></div>

Page 93: Applications: A Series of States

render: function(){this.$el.append(new PurchasesFilterView().render());

_.each(this.collection.models, function (item) { this.$el.append(new PurchaseRowView({model: item})

.render()); }, this); }

Page 94: Applications: A Series of States
Page 95: Applications: A Series of States
Page 96: Applications: A Series of States
Page 97: Applications: A Series of States

app.PurchaseRowView = Backbone.View.extend({...

events: { 'click': 'toggleMoreDetails' }, toggleMoreDetails: function(){ this.model.toggleMoreDetails(); this.$el.toggleClass( 'selected', this.moreDetailsShowing); }});

Page 98: Applications: A Series of States
Page 99: Applications: A Series of States
Page 100: Applications: A Series of States
Page 101: Applications: A Series of States
Page 102: Applications: A Series of States
Page 103: Applications: A Series of States
Page 104: Applications: A Series of States
Page 105: Applications: A Series of States

truth-in-data

truth-in-datatruth-in-data

Page 106: Applications: A Series of States

model.on(‘change’)/collection.on(‘change’)

-> render

model.on(‘change’)-> render

model.on(‘change’)-> render

Page 107: Applications: A Series of States

{}

Page 108: Applications: A Series of States
Page 109: Applications: A Series of States
Page 110: Applications: A Series of States

<div id=”purchase-list”>

<div id=”details”></div>

<div id=”dashboard”>

</div>

<div id=”sidebar”>

</div>

<div id=”map”></div>

</div>

Page 111: Applications: A Series of States

app.DashboardView = Backbone.View.extend({ render: function(){

this.$el.append(new app.PurchaesView().render().el);this.$el.append(new app.PurchaesMapView().render().el);this.$el.append(new app.PurcaseDetailView().render().el);

}});

Page 113: Applications: A Series of States

<div id=”purchase-list”>

<div id=”details”></div>

<div id=”dashboard”>

</div>

<div id=”sidebar”>

</div>

<div id=”map”></div>

</div>

Page 114: Applications: A Series of States
Page 115: Applications: A Series of States
Page 116: Applications: A Series of States
Page 117: Applications: A Series of States
Page 118: Applications: A Series of States

possible, but you must be cautious

Page 119: Applications: A Series of States
Page 120: Applications: A Series of States
Page 121: Applications: A Series of States
Page 122: Applications: A Series of States

{{view App.NavigationView}}

{{view App.SummaryView}}

Page 123: Applications: A Series of States

{{ outlet }}

Page 124: Applications: A Series of States
Page 125: Applications: A Series of States
Page 126: Applications: A Series of States
Page 127: Applications: A Series of States
Page 128: Applications: A Series of States
Page 129: Applications: A Series of States
Page 130: Applications: A Series of States
Page 131: Applications: A Series of States
Page 132: Applications: A Series of States

Purchases

Index Viewing Editing

Page 133: Applications: A Series of States

Purchases

Index Viewing Editing

Page 134: Applications: A Series of States

Purchases

Index Viewing Editing

Page 135: Applications: A Series of States

Purchases

Index Viewing Editing

Page 136: Applications: A Series of States

Purchases

Index Viewing Editing

Page 137: Applications: A Series of States

Purchases

Index Viewing Editing

Page 138: Applications: A Series of States

Purchases

Index Viewing Editing

Page 139: Applications: A Series of States

Purchases

Index Viewing Editing

Page 140: Applications: A Series of States

Purchases

Index Viewing Editing

Page 141: Applications: A Series of States

Purchases

Index Viewing Editing

Page 142: Applications: A Series of States

Purchases

Index Viewing Editing

Page 143: Applications: A Series of States

App = Ember.Application.create();

App.ApplicationView = Ember.View.extend({ templateName: 'application'});

App.ApplicationController = Ember.Controller.extend();

App.Router = Ember.Route.extend({ root: Ember.Route.extend({}) // this happens for you: ‘shared instance’// applicationController: App.ApplicationController.create()

})

Page 144: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 145: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 146: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 147: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 148: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 149: Applications: A Series of States

Purchases

Index Viewing Editing

Page 150: Applications: A Series of States

App = Ember.Application.create();

App.ApplicationView = Ember.View.extend({ templateName: 'application'});

App.ApplicationController = Ember.Controller.extend();

App.Router = Ember.Route.extend({ root: Ember.Route.extend({})})

Page 151: Applications: A Series of States

App = Ember.Application.create();

App.ApplicationView = Ember.View.extend({ templateName: 'application'});

App.ApplicationController = Ember.Controller.extend();

App.Router = Ember.Route.extend({ root: Ember.Route.extend({ purchases: Ember.Route.extend({ index: Ember.Route.extend({ }) }) })});

Page 152: Applications: A Series of States

{{view App.NavigationView}}{{view App.SummaryView}}

{{outlet mainArea}}{{outlet detailsArea}}

application.handlebars

Page 153: Applications: A Series of States

App = Ember.Application.create();

App.ApplicationView = Ember.View.extend({ templateName: 'application'});

App.ApplicationController = Ember.Controller.extend();

App.Router = Ember.Route.extend({ root: Ember.Route.extend({ purchases: Ember.Route.extend({ index: Ember.Route.extend({ }) }) })});

Page 154: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ })})

Page 155: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ connectOutlets: function(router){

var controller = router.get('applicationController'), purchases = App.Purchase.find(), locations = purchases.get('locations'); controller.connectOutlet('mainArea', 'purchaseList', purchases); controller.connectOutlet('detailsArea', 'map', locations); } })})

Page 156: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ connectOutlets: function(router){

var controller = router.get('applicationController'), purchases = App.Purchase.find(), locations = purchases.get('locations'); controller.connectOutlet('mainArea', 'purchaseList', purchases); controller.connectOutlet('detailsArea', 'map', locations); } })})

where? what? data context?

Page 157: Applications: A Series of States

controller.connectOutlet('mainArea', 'purchaseList', purchases);

Page 158: Applications: A Series of States

controller.connectOutlet('mainArea', 'purchaseList', purchases);

App.PurchaseListView = Ember.View.extend({ templateName: 'purchaseList'});App.PurchaseListController = Ember.ArrayController.extend();

Page 159: Applications: A Series of States

Ember.ArrayController.extend();

proxy/presenter/controller/thingie

Page 160: Applications: A Series of States

proxy

content

Page 161: Applications: A Series of States

proxy

content

what’s your length?

Page 162: Applications: A Series of States

proxy

content

how are you sorted?

Page 163: Applications: A Series of States

controller.connectOutlet('mainArea', 'purchaseList', purchases);

App.PurchaseListView = Ember.View.extend({ templateName: 'purchaseList'});App.PurchaseListController = Ember.ArrayController.extend();

Page 164: Applications: A Series of States

controller.connectOutlet('mainArea', 'purchaseList', purchases);

App.PurchaseListView = Ember.View.extend({ templateName: 'purchaseList'});App.PurchaseListController = Ember.ArrayController.extend();

{{#each purchase in controller}} <li> {{purchase.date}} {{purchase.location}} {{purchase.amount}} </li>{{/each}}

Page 165: Applications: A Series of States

controller.connectOutlet('mainArea', 'purchaseList', purchases);

App.PurchaseListView = Ember.View.extend({ templateName: 'purchaseList'});App.PurchaseListController = Ember.ArrayController.extend();

{{#each purchase in controller}} <li> {{purchase.date}} {{purchase.location}} {{purchase.amount}} </li>{{/each}}

Page 166: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ connectOutlets: function(router){

var controller = router.get('applicationController'), purchases = App.Purchase.find(), locations = purchases.get('locations'); controller.connectOutlet('mainArea', 'purchaseList', purchases); controller.connectOutlet('detailsArea', 'map', locations); } })})

Page 167: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ connectOutlets: function(router){

var controller = router.get('applicationController'), purchases = App.Purchase.find(), locations = purchases.get('locations'); controller.connectOutlet('mainArea', 'purchaseList', purchases); controller.connectOutlet('detailsArea', 'map', locations); } })})

where? what? data context?

Page 168: Applications: A Series of States

controller.connectOutlet('detailsArea', 'map', locations);

Page 169: Applications: A Series of States

App.MapView = Ember.View.extend({ templateName: 'googleMap'});App.MapController = Ember.ArrayController.extend();

controller.connectOutlet('detailsArea', 'map', locations);

Page 170: Applications: A Series of States

controller.connectOutlet('detailsArea', 'map', locations);

App.MapView = Ember.View.extend({ templateName: 'googleMap'});App.MapController = Ember.ArrayController.extend();

Page 171: Applications: A Series of States

controller.connectOutlet('detailsArea', 'map', locations);

App.MapView = Ember.View.extend({ templateName: 'googleMap'});App.MapController = Ember.ArrayController.extend();

Page 172: Applications: A Series of States

controller.connectOutlet('detailsArea', 'map', locations);

App.MapView = Ember.View.extend({ templateName: 'googleMap'});App.MapController = Ember.ArrayController.extend();

Page 173: Applications: A Series of States

Purchases

Index Viewing Editing

Page 174: Applications: A Series of States

Purchases

Index Viewing Editing

Page 175: Applications: A Series of States

{{#each purchase in controller}} <li> {{purchase.date}} {{purchase.location}} {{purchase.amount}} </li>{{/each}}

Page 176: Applications: A Series of States

{{#each purchase in controller}} <li {{action showDetails purchase}}> {{purchase.date}} {{purchase.location}} {{purchase.amount}} </li>{{/each}}

Page 177: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ connectOutlets: function(router){

... } })})

Page 178: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } })})

Page 179: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ })

})

Page 180: Applications: A Series of States

Purchases

Index Viewing Editing

Page 181: Applications: A Series of States

Purchases

Index Viewing Editing

Page 182: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

where? what? data context?

Page 183: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

Page 184: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

{{#each purchase in controller}} <li {{action showDetails purchase}}> {{purchase.date}} {{purchase.location}} {{purchase.amount}} </li>{{/each}}

Page 185: Applications: A Series of States

controller.connectOutlet('detailsArea', 'purchaseDetails', context);

Page 186: Applications: A Series of States

controller.connectOutlet('detailsArea', 'purchaseDetails', context);

App.PurchaseDetailsView = Ember.View.extend({ templateName: 'details'});App.PurchaseDetailsController = Ember.ObjectController.extend();

Page 187: Applications: A Series of States

controller.connectOutlet('detailsArea', 'purchaseDetails', context);

App.PurchaseDetailsView = Ember.View.extend({ templateName: 'details'});App.PurchaseDetailsController = Ember.ObjectController.extend();

Page 188: Applications: A Series of States

<div class='actions'> <a {{action editPurchase content}}>

Edit</a>

<a href='...'>Support</a></div>

{{#if pending}} <h3>

This transaction is pending...</h3>

{{/if}}

{{name}}{{amount}}{{label}}

App.PurchaseDetailsView = Ember.View.extend({ templateName: 'details'});App.PurchaseDetailsController = Ember.ObjectController.extend();

Page 189: Applications: A Series of States

App.PurchaseDetailsView = Ember.View.extend({ templateName: 'details'});App.PurchaseDetailsController = Ember.ObjectController.extend();

<div class='actions'> <a {{action editPurchase content}}>

Edit</a>

<a href='...'>Support</a></div>

{{#if pending}} <h3>

This transaction is pending...</h3>

{{/if}}

{{name}}{{amount}}{{label}}

Page 190: Applications: A Series of States

Ember.ObjectController.extend();

Page 191: Applications: A Series of States

proxy

content

Ember.ObjectController.extend();

Page 192: Applications: A Series of States

proxy

content

are you pending?

Page 193: Applications: A Series of States

App.PurchaseDetailsView = Ember.View.extend({ templateName: 'details'});App.PurchaseDetailsController = Ember.ObjectController.extend();

<div class='actions'> <a {{action editPurchase content}}>

Edit</a>

<a href='...'>Support</a></div>

{{#if pending}} <h3>

This transaction is pending...</h3>

{{/if}}

{{name}}{{amount}}{{label}}

Page 194: Applications: A Series of States
Page 195: Applications: A Series of States

Purchases

Index Viewing Editing

Page 196: Applications: A Series of States

Purchases

Index Viewing Editing

Page 197: Applications: A Series of States

<div class='actions'> <a {{action editPurchase content}}>

Edit</a>

<a href='...'>Support</a></div>

{{#if pending}} <h3>

This transaction is pending...</h3>

{{/if}}

{{name}}{{amount}}{{label}}

Page 198: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

Page 199: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }), viewing: Ember.Route.extend({ editPurchase: Ember.Route.transitionTo(‘editing’), connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

Page 200: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }),editing: Ember.Route.extend({ connectOutlets: function(router, context){

var controller = router.get('applicationController'); controller. connectOutlet('detailsArea', 'editPurchaseDetails', context); }}),

viewing: Ember.Route.extend({ editPurchase: Ember.Route.transitionTo(‘editing’), connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

Page 201: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }),editing: Ember.Route.extend({ connectOutlets: function(router, context){

var controller = router.get('applicationController'); controller. connectOutlet('detailsArea', 'editPurchaseDetails', context); }}),

viewing: Ember.Route.extend({ editPurchase: Ember.Route.transitionTo(‘editing’), connectOutlets: function(router, context){ var controller = router.get('applicationController'); controller.

connectOutlet('detailsArea', 'purchaseDetails', context);}

})})

where? what? data context?

Page 202: Applications: A Series of States

connectOutlet('detailsArea', 'editPurchaseDetails', context);

Page 203: Applications: A Series of States

connectOutlet('detailsArea', 'editPurchaseDetails', context);

App.EditPurchaseDetailsView = Ember.View.extend({ templateName: 'edit-details'});App.EditPurchaseDetailsController = Ember.ObjectController.extend();

Page 204: Applications: A Series of States

connectOutlet('detailsArea', 'editPurchaseDetails', context);

App.EditPurchaseDetailsView = Ember.View.extend({ templateName: 'edit-details'});App.EditPurchaseDetailsController = Ember.ObjectController.extend();

<a {{action save context}}>Save</a><a {{action cancel}}>Cancel</a>

{{view Ember.TextField valueBinding="name"}}

Page 205: Applications: A Series of States

connectOutlet('detailsArea', 'editPurchaseDetails', context);

App.EditPurchaseDetailsView = Ember.View.extend({ templateName: 'edit-details'});App.EditPurchaseDetailsController = Ember.ObjectController.extend();

<a {{action save context}}>Save</a><a {{action cancel}}>Cancel</a>

{{view Ember.TextField valueBinding="name"}}

Page 206: Applications: A Series of States

Ember.ObjectController.extend();

Page 207: Applications: A Series of States

proxy

content

Ember.ObjectController.extend();

Page 208: Applications: A Series of States

proxy

content

what’s your name?

Page 209: Applications: A Series of States
Page 210: Applications: A Series of States
Page 211: Applications: A Series of States

Purchases

Index Viewing Editing

Page 212: Applications: A Series of States

Purchases

Index Viewing Editing

Page 213: Applications: A Series of States

purchases: Ember.Route.extend({ index: Ember.Route.extend({ showDetails: Ember.Route.transitionTo(‘viewing’), connectOutlets: function(router){

... } }),editing: Ember.Route.extend({ saveChanges: Ember.Route.transitionTo(‘index’), connectOutlets: function(router, context){

... }}),

viewing: Ember.Route.extend({ editPurchase: Ember.Route.transitionTo(‘editing’), connectOutlets: function(router, context){

... })})

Page 214: Applications: A Series of States

Purchases

Index Viewing Editing

Page 215: Applications: A Series of States

Demeter’d

Page 216: Applications: A Series of States

https://gist.github.com/3981133

Page 217: Applications: A Series of States
Page 218: Applications: A Series of States

> 7 views

Page 219: Applications: A Series of States
Page 220: Applications: A Series of States
Page 221: Applications: A Series of States
Page 222: Applications: A Series of States
Page 223: Applications: A Series of States

which pattern, when?

Page 224: Applications: A Series of States

• app is just a series of documents• or you’re just coding single page• not a client app• manipulation mostly presentational• few data communications• user interaction brief, simple, infrequent

Page 225: Applications: A Series of States

• app is series of documents• with “islands of richness”• occassional data communications• multiple parts of a page need to reflect data• shallow view hierarchy (1-2 levels)• small number of views (~7)• user interaction brief and/or infrequent

Page 226: Applications: A Series of States

• frequent data communications• many parts of a page need to reflect data• deep view hierarchy (2-3+)• large number of views• user will remain for large amounts of time• and/or frequently return• server is just an api• you’d *almost* write a desktop/iOS app

Page 227: Applications: A Series of States

Mobile Cocoa TouchAndroid SDK

Desktop Cocoa.NET

Web ?

Page 228: Applications: A Series of States

Mobile Cocoa TouchAndroid SDK

Desktop Cocoa.NET

Web

Page 229: Applications: A Series of States

User Interface HTML+CSS

Data Persistence

Application Architecture

Page 230: Applications: A Series of States

fin