Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Wer bin Ich? • Adam Hawkins • broadcastingadam.com • twitter.com/adman65 • github.com/twinturbo • speaker.com/u/twinturbo • Jeden Tag arbeite ich an ember Apps

Slide 3

Slide 3 text

How to Avoid This Feeling

Slide 4

Slide 4 text

Express Your Application in Handlebars

Slide 5

Slide 5 text

Bad BlogPostView = Ember.CollectionView.extend({ elementId: 'posts', classNames: ['post-list'], itemViewClass: Ember.View.extend({ // your stuff here classNames: ['post'], }) });

Slide 6

Slide 6 text

Good
    {{each controller}}
  • {{title}}

    {{text}}
  • {{/each}}

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Views bind to Controllers

Slide 9

Slide 9 text

Bad

Baz: {{someHelper "App.foo.bar.baz"}}

Slide 10

Slide 10 text

Good ViewController = Ember.Controller.extend({ bazBinding: Ember.Binding "App.foo.bar.baz" })

Baz: {{someHelper baz}}

Slide 11

Slide 11 text

• Just because you can reach out, doesn’t mean you should • Views use their controller, not others • Controller provides everything a view needs Why?

Slide 12

Slide 12 text

Router Handles Persistent State

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Unbind Event Listeners (when you need to)

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Respect the following diagram

Slide 17

Slide 17 text

• 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

Slide 18

Slide 18 text

If you only remember one thing: remember the diagram

Slide 19

Slide 19 text

DS.FixtureAdapter

Slide 20

Slide 20 text

Slide 21

Slide 21 text

SCHEIßE DINGE

Slide 22

Slide 22 text

Slide 23

Slide 23 text

• 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?

Slide 24

Slide 24 text

Was ist besser?

Slide 25

Slide 25 text

Respect the Boundary in the Diagram

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Bad Post.FIXTURES = [ { id: "1", title: "Post 1", text: "Lorem...." comment_ids: ["1", "2"] } ] Comment.FIXTURES = [ { id: "1" text: "Zomg" post_id: "1" } ]

Slide 28

Slide 28 text

Good post = Post.createRecord({ title: "Post 1" text: "Lorem..." }); comment = Comment.createRecord({ text: "Zomg" }); post.get('comments').pushObject(comment); store.commit()

Slide 29

Slide 29 text

Respect the Boundary

Slide 30

Slide 30 text

Test the application independently from data sources

Slide 31

Slide 31 text

Test data source interaction at the adapter level

Slide 32

Slide 32 text

• 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

Slide 33

Slide 33 text

Ende Wer hast eine Frage?