Ember.js Application Patterns

Ember.js Application Patterns

94378c403019af23a28b08447a34b8e0?s=128

Adam Hawkins

January 21, 2013
Tweet

Transcript

  1. Application Patterns tw://adman65 - gh://twinturbo - me@broadcastingadam.com -präsentiert in Hamburg

  2. Wer bin Ich? • Adam Hawkins • broadcastingadam.com • twitter.com/adman65

    • github.com/twinturbo • speaker.com/u/twinturbo • Jeden Tag arbeite ich an ember Apps
  3. How to Avoid This Feeling

  4. Express Your Application in Handlebars

  5. Bad BlogPostView = Ember.CollectionView.extend({ elementId: 'posts', classNames: ['post-list'], itemViewClass: Ember.View.extend({

    // your stuff here classNames: ['post'], }) });
  6. Good <ul id="posts"> {{each controller}} <li class="post"> <h2>{{title}}</h2> {{text}} </li>

    {{/each}} </ul>
  7. Why? • More designer friendly • Styling and markup is

    not application level, it’s presentation • Hard to track down where markup happens • Break this rule: when you have more complex views
  8. Views bind to Controllers

  9. Bad <p> Baz: {{someHelper "App.foo.bar.baz"}} </p>

  10. Good ViewController = Ember.Controller.extend({ bazBinding: Ember.Binding "App.foo.bar.baz" }) <p> Baz:

    {{someHelper baz}} </p>
  11. • Just because you can reach out, doesn’t mean you

    should • Views use their controller, not others • Controller provides everything a view needs Why?
  12. Router Handles Persistent State

  13. if(stateAccessibleViaURL) { app.stickInRouter(); } else { app.stickInController(); }

  14. Unbind Event Listeners (when you need to)

  15. Ember.View.extend({ // we need a reference to this resizeListener: (function({

    $.proxy this.windowDidResize, this }).property(), windowDidResize: function({ // your logic here }), didInsertElement: function({ $(window).on('resize', this.resizeListener) }), didRemoveElement: function({ $(window).off('resize', this.resizeListener) }) });
  16. Respect the following diagram

  17. • Respect the boundary at the top • User’s interact

    with your app via the URL and DOM • Controllers do most of the work • Handlebars represents the UI at any given point • Controllers don’t interact directly with views • Views interact with the DOM via didInsertElement and friends
  18. If you only remember one thing: remember the diagram

  19. DS.FixtureAdapter

  20. <rant>

  21. SCHEIßE DINGE

  22. </rant>

  23. • Forces your mind into an API box • Extremely

    test unfriendly • Development & testing concerns mix with production concerns • Fixtures are not application model, they are API responses Wieso?
  24. Was ist besser?

  25. Respect the Boundary in the Diagram

  26. DS.InMemoryAdapter • Uses a “pass through” serializer • Instantiate the

    DS.Model objects you want and call commit() • No need to track FK’s. Just add to the association and call commit() • Focus on application data • Leverage the boundary for your benefit
  27. Bad Post.FIXTURES = [ { id: "1", title: "Post 1",

    text: "Lorem...." comment_ids: ["1", "2"] } ] Comment.FIXTURES = [ { id: "1" text: "Zomg" post_id: "1" } ]
  28. Good post = Post.createRecord({ title: "Post 1" text: "Lorem..." });

    comment = Comment.createRecord({ text: "Zomg" }); post.get('comments').pushObject(comment); store.commit()
  29. Respect the Boundary

  30. Test the application independently from data sources

  31. Test data source interaction at the adapter level

  32. • Ember.Binding.oneWay when applicable • Ember.Computed.alias (in the works) •

    Use a build tool (Iridium is the best) • If using Rails + Ember Data, then use ActiveModel::Serializers • Push async code to the edge of your application • Controllers decorate objects Grab Bag
  33. Ende Wer hast eine Frage?