Services & Component Collaboration

Services & Component Collaboration

Talk given June 2014 on the Ember.js Hangout On Air

2956e2cd2664630aa968b92bbb645f2f?s=128

Kerrick Long

June 17, 2014
Tweet

Transcript

  1. SERVICES & COMPONENT COLLABORATION

  2. Kerrick Long Things I make and do Where to find

    me online meetup.com/STLEmber Lead Front-end Developer at Second Street www.KerrickLong.com twitter.com/KerrickLong github.com/Kerrick
  3. SERVICES WHAT ARE ANYWAYS?

  4. None
  5. ACCESSIBLE

  6. ACCESSIBLE SHAREABLE

  7. ACCESSIBLE SHAREABLE FUNCTIONALITY

  8. ACCESSIBLE SHAREABLE FUNCTIONALITY SINGLETONS

  9. ACCESSIBLE SHAREABLE FUNCTIONALITY SINGLETONS

  10. ACCESSIBLE this.get('store')

  11. ACCESSIBLE this.get('mine')

  12. ACCESSIBLE SHAREABLE FUNCTIONALITY SINGLETONS

  13. SHAREABLE this.get('openHouses')

  14. SHAREABLE this NOPE!

  15. SHAREABLE this.get('geolocation')

  16. SHAREABLE this.get('facebook')

  17. ACCESSIBLE SHAREABLE FUNCTIONALITY SINGLETONS

  18. FUNCTIONALITY this.get('geolocation') .getProperties( 'latitude', 'longitude' )

  19. FUNCTIONALITY this.get('facebook') .getLoginStatus() .then(function(response) { // Do things })

  20. FUNCTIONALITY ACCESSIBLE SHAREABLE SINGLETONS

  21. SINGLETONS this.get('geolocation') .askPermission() .then(success, failure)

  22. SINGLETONS this.get('geolocation') .set('watch', true)

  23. ACCESSIBLE SHAREABLE FUNCTIONALITY SINGLETONS SINGLETONS

  24. None
  25. App.GeolocationService = Ember.Service.extend({ getPosition: function() { /* Logic */ }

    }) App.NearbyTweetsRoute = Ember.Route.extend({ model: function() { return this.get('services.geolocation') .getPosition().then(function(loc) { return this.get('services.twitter') .findNearbyTweets(loc); }.bind(this)); } })
  26. “I hope this can be a starting point for the

    community to start evolving on our shared understanding of what services are.” — Tom Dale
  27. “I want it NOW!” — Veruca Salt

  28. App.GeolocationService = Ember.Object.extend({ // Awesome code })

  29. Ember.Application.initializer({ name: 'service:geolocation', initialize: function(container, application) { container.register( 'service:geolocation', App.GeolocationService,

    { singleton: true } ) } })
  30. Ember.Application.initializer({ name: 'injectGeolocation', before: 'geolocation', initialize: function(container, application) { var

    n='geolocation', l='service:geolocation' application.inject('controller', n, l) application.inject('route', n, l) } });
  31. COMPONENT COLLABORATION HOW CAN LEAD ME TO HTML’S FUTURE?

  32. HTML’S FUTURE? HTML’S PAST.

  33. <ol> <li>One</li> <li>Two</li> <li>Two</li> </ol>

  34. <select> <optgroup label="Colors"> <option>Red</option> <option>Blue</option> </optgroup> </select>

  35. None
  36. None
  37. <x-accordion> <acc-item> <acc-title>Foo</acc-title> <acc-content>Bar</acc-content> </acc-item> <acc-item> <acc-title>Baz</acc-title> <acc-content>Bing</acc-content> </acc-item> </x-accordion>

  38. {{#x-accordion}} {{#acc-item}} {{#acc-title}}Foo{{/acc-title}} {{#acc-content}}Bar{{/acc-content}} {{/acc-item}} {{#acc-item}} {{#acc-title}}Baz{{/acc-title}} {{#acc-content}}Bing{{/acc-content}} {{/acc-item}} {{/x-accordion}}

  39. App.XAccordionComponent = Em.Component.extend({ tagName: 'x-accordion', init: function() { this._super() this.set('accordionItems',

    Em.ArrayProxy.create({ content: [] })) }, registerItem: function(accordionItem) { this.get('accordionItems').addObject(accordionItem) }, activeItem: null, toggleItem: function(accordionItem) { var isActive = accordionItem === this.get('activeItem') var newActiveItem = isActive ? null : accordionItem this.set('activeItem', newActiveItem) } })
  40. App.XAccordionComponent = Em.Component.extend({ tagName: 'x-accordion', init: function() { this._super() this.set(‘accordionItems',

    Em.ArrayProxy.create({ content: [] })) }, registerItem: function(accordionItem) { this.get(‘accordionItems').addObject(accordionItem) }, activeItem: null, toggleItem: function(accordionItem) { var isActive = accordionItem === this.get('activeItem') var newActiveItem = isActive ? null : accordionItem this.set('activeItem', newActiveItem)
  41. App.XAccordionComponent = Em.Component.extend({ tagName: 'x-accordion', init: function() { this._super() this.set('accordionItems',

    Em.ArrayProxy.create({ content: [] })) }, registerItem: function(accordionItem) { this.get('accordionItems').addObject(accordionItem) }, activeItem: null, toggleItem: function(accordionItem) { var isActive = accordionItem === this.get('activeItem') var newActiveItem = isActive ? null : accordionItem this.set('activeItem', newActiveItem) } })
  42. App.AccItemComponent = Em.Component.extend({ tagName: 'acc-item', accordion: Em.computed.alias('parentView'), init: function() {

    this._super() this.get('accordion').registerItem(this) }, isExpanded: Em.computed.equal('accordion.activeItem', '@this') })
  43. App.AccItemComponent = Em.Component.extend({ tagName: 'acc-item', accordion: Em.computed.alias('parentView'), init: function() {

    this._super() this.get('accordion').registerItem(this) }, isExpanded: Em.computed.equal('accordion.activeItem', '@this') })
  44. App.AccItemComponent = Em.Component.extend({ tagName: 'acc-item', accordion: Em.computed.alias('parentView'), init: function() {

    this._super() this.get('accordion').registerItem(this) }, isExpanded: Em.computed.equal('accordion.activeItem', '@this') })
  45. App.AccTitleComponent = Em.Component.extend({ tagName: ‘acc-title', accordionItem: Em.computed.alias('parentView'), accordion: Em.computed.alias('accordionItem.parentView'), toggle:

    function() { this.get('accordion').toggleItem(this.get('accordionItem')) }.on('click') })
  46. App.AccTitleComponent = Em.Component.extend({ tagName: ‘acc-title', accordionItem: Em.computed.alias('parentView'), accordion: Em.computed.alias('accordionItem.parentView'), toggle:

    function() { this.get('accordion').toggleItem(this.get('accordionItem')) }.on('click') })
  47. App.AccTitleComponent = Em.Component.extend({ tagName: ‘acc-title', accordionItem: Em.computed.alias('parentView'), accordion: Em.computed.alias('accordionItem.parentView'), toggle:

    function() { this.get('accordion') .toggleItem(this.get('accordionItem')) }.on('click') })
  48. App.AccContentComponent = Em.Component.extend({ tagName: 'acc-content', accordionItem: Em.computed.alias('parentView'), isVisible: Em.computed.alias('accordionItem.isExpanded') })

  49. App.AccContentComponent = Em.Component.extend({ tagName: 'acc-content', accordionItem: Em.computed.alias('parentView'), isVisible: Em.computed.alias('accordionItem.isExpanded') })

  50. App.AccContentComponent = Em.Component.extend({ tagName: 'acc-content', accordionItem: Em.computed.alias('parentView'), isVisible: Em.computed.alias('accordionItem.isExpanded') })

  51. {{#x-accordion}} {{#acc-item}} {{#acc-title}}Foo{{/acc-title}} {{#acc-content}}Bar{{/acc-content}} {{/acc-item}} {{#acc-item}} {{#acc-title}}Baz{{/acc-title}} {{#acc-content}}Bing{{/acc-content}} {{/acc-item}} {{/x-accordion}}

  52. HEY, WAIT!

  53. HEY, WAIT! TIE IT ALL TOGETHER. THERE IS NO COHESIVENESS

    TO THOSE TOPICS. YOU REALLY SHOULD DO SOMETHING TO MAKE YOUR TALK FEEL LIKE AN ORGANIZED WHOLE. IF YOU’RE NOT EVEN GOING TO BOTHER WITH SOME SORT OF CONCLUSION TO ROUND UP EVERYTHING YOU JUST TALKED ABOUT, THEN WHAT ARE WE ALL EVEN DOING HERE ANYWAYS?