Upgrade to Pro — share decks privately, control downloads, hide ads and more …

applications: a series of states

applications: a series of states

Video: https://vimeo.com/65504071

An exploration of application structure patterns, from purely server oriented request/response flow to fully featured client applications in the browser

Trek Glowacki

November 16, 2012
Tweet

More Decks by Trek Glowacki

Other Decks in Programming

Transcript

  1. {}

  2. { 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' } }
  3. 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); }
  4. 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); }
  5. 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); } });
  6. 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)) } });
  7. app.PurchaseRowView = Backbone.View.extend({ ... events: { 'click': 'toggleMoreDetails' }, toggleMoreDetails:

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

  9. 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() })
  10. 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({}) })
  11. 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({ }) }) }) });
  12. 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({ }) }) }) });
  13. 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); } }) })
  14. 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?
  15. 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}}
  16. 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}}
  17. 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); } }) })
  18. 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?
  19. 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?
  20. 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); } }) })
  21. 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}}
  22. <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();
  23. 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}}
  24. 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}}
  25. <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}}
  26. 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); } }) })
  27. 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); } }) })
  28. 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); } }) })
  29. 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?
  30. 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"}}
  31. 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"}}
  32. 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){ ... }) })
  33. • 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
  34. • 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
  35. • 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
  36. fin