Slide 1

Slide 1 text

Ember: The Magic, Demystified

Slide 2

Slide 2 text

Who the heck is this guy? ● Ember Core Team ● General OSS addict ● DockYarder twitter: rwjblue github: rjackson

Slide 3

Slide 3 text

Sweet Ember Shirts

Slide 4

Slide 4 text

Sweet Ember Shirts

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Ember: The Magic, Demystified

Slide 7

Slide 7 text

Magic Naming?

Slide 8

Slide 8 text

Items to review: ● Lookup From Routes to Templates ● Component Lookup

Slide 9

Slide 9 text

Route Lookup

Slide 10

Slide 10 text

Route Lookup ● Route ● Controller ● View ● Template

Slide 11

Slide 11 text

Route Lookup // app/router.js var Router = Ember.Router.extend(); Router.map(function() { this.route('posts'); }); export default Router;

Slide 12

Slide 12 text

Route Lookup {{! /app/templates/posts.hbs }}

Woot!! You found the posts route!

Slide 13

Slide 13 text

Route Lookup http://locahost:4200/posts How does this:

Slide 14

Slide 14 text

Route Lookup End up with this?

Slide 15

Slide 15 text

Route Lookup var Klass = require('sample-app/app')['default']; window.SampleApp = Klass.create(); Ember.Application.create

Slide 16

Slide 16 text

Route Lookup this.setupEventDispatcher(); this.ready(); // user hook this.startRouting(); this.resolve(this); Ember.Application#didBecomeReady

Slide 17

Slide 17 text

Route Lookup this.setupEventDispatcher(); this.ready(); // user hook this.startRouting(); this.resolve(this); Ember.Application#didBecomeReady

Slide 18

Slide 18 text

Route Lookup this.constructor.map(Ember.K); this._setupRouter(router, location); this.handleURL(‘/posts’); Ember.Router#startRouting

Slide 19

Slide 19 text

Route Lookup var dsl = DSL.map(function() { this.resource( 'application', { path: "/" }, function() { callback.call(this); }); }); Ember.Router.map

Slide 20

Slide 20 text

Route Lookup var dsl = DSL.map(function() { this.resource( 'application', { path: "/" }, function() { callback.call(this); }); }); Ember.Router.map

Slide 21

Slide 21 text

Route Lookup - Deep Dive Ember.Router#_setupRouter ● Sets `router.getHandler` ● Sets URL update hooks

Slide 22

Slide 22 text

Route Lookup var R = container.lookupFactory('route:basic') return function(name) { var handler = this.container.lookup('route:' + name); handler.routeName = name; if (handler) { return handler;} this.container.register('route:' + name, R.extend()); return this.container.lookup('route:' + name); }; Ember.Router#_getHandlerFunction

Slide 23

Slide 23 text

Route Lookup ● Router.map sets up the handlers ● router.js handles the actual route transitions ● New route is entered: getHandler(‘posts’) ● So we have a Route instance, now what?

Slide 24

Slide 24 text

Route Rendering ● router.js invokes various async hooks (activate, model, redirect, etc) ● router.js invokes route.setup

Slide 25

Slide 25 text

Route Rendering var controllerName = this.controllerName || this.routeName, controller = this.controllerFor(controllerName, true); if (!controller) { controller = this.generateController(controllerName,context); } Ember.Route#setup

Slide 26

Slide 26 text

Route Rendering this.setupController(controller, context, transition); this.renderTemplate(controller, context); Ember.Route#setup

Slide 27

Slide 27 text

Route Rendering var name = this.routeName; var templateName = this.templateName || name; var viewName = this.viewName || name; Ember.Route#render

Slide 28

Slide 28 text

Route Rendering var view = container.lookup('view:' + viewName), template = view ? view.get('template') : null; if (!template) { template = container.lookup('template:' + templateName); } Ember.Route#render

Slide 29

Slide 29 text

Route Rendering options = normalizeOptions(this, name, template, options); view = setupView(view, container, options); appendView(this, view, options); Ember.Route#render

Slide 30

Slide 30 text

Route Lookup app/routes/posts.js app/controllers/posts.js app/views/posts.js app/templates/posts.hbs Files looked up:

Slide 31

Slide 31 text

Route Lookup app/routes/posts.js app/controllers/posts.js app/views/posts.js app/templates/posts.hbs Files looked up:

Slide 32

Slide 32 text

Route Lookup // packages/ember-routing/lib/system/router.js#L319 // Ember.Router#_getHandlerFunction var handler = this.container.lookup('route:' + name); handler.routeName = name; app/routes/posts.js

Slide 33

Slide 33 text

Route Lookup app/routes/posts.js app/controllers/posts.js app/views/posts.js app/templates/posts.hbs Files looked up:

Slide 34

Slide 34 text

Route Lookup // packages/ember-routing/lib/system/route.js#L696 // Ember.Route#setup controller = this.controllerFor(controllerName, true); if (!controller) { controller = this.generateController(controllerName,context); } app/controllers/posts.js

Slide 35

Slide 35 text

Route Lookup app/routes/posts.js app/controllers/posts.js app/views/posts.js app/templates/posts.hbs Files looked up:

Slide 36

Slide 36 text

Route Lookup // packages/ember-routing/lib/system/route.js#L1377 // Ember.Route#render view = container.lookup('view:' + viewName), view = setupView(view, container, options); appendView(this, view, options); app/views/posts.js

Slide 37

Slide 37 text

Route Lookup app/routes/posts.js app/controllers/posts.js app/views/posts.js app/templates/posts.hbs Files looked up:

Slide 38

Slide 38 text

Route Lookup app/templates/posts.hbs // packages/ember-routing/lib/system/route.js#L1381 // Ember.Route#render template = view ? view.get('template') : null; template = template || container.lookup('template:' + templateName); options = normalizeOptions(this, name, template, options); view = setupView(view, container, options);

Slide 39

Slide 39 text

Component Lookup

Slide 40

Slide 40 text

Component Lookup ● Layout ● Component

Slide 41

Slide 41 text

// app/templates/application.hbs {{x-foo bar="baz"}} // app/templates/components/x-foo.hbs {{foobar}} Component Lookup Templates:

Slide 42

Slide 42 text

export default Ember.Component.extend({ foobar: Ember.computed('bar', function() { return 'foo' + Ember.get(this, 'bar'); }) }); Component Lookup Component: x-foo

Slide 43

Slide 43 text

var id = new Handlebars.AST.IdNode([{ part: '_triageMustache' }]); mustache = new Handlebars.AST.MustacheNode( [id].concat([mustache.id]), mustache.hash, !mustache.escaped ); return Handlebars.Compiler.prototype.mustache.call(this, mustache); Component Lookup Ember.Handlebars.Compiler.mustache

Slide 44

Slide 44 text

var helper = EmberHandlebars.resolveHelper( options.data.view.container, property ); if (helper) { return helper.call(this, options); } Component Lookup _triageMustacheHelper

Slide 45

Slide 45 text

var componentLookup = container.lookup('component-lookup:main'); var Component = componentLookup.lookupFactory(name, container); if (Component) { helper = EmberHandlebars.makeViewHelper(Component); container.register('helper:' + name, helper); } Component Lookup resolveHelper

Slide 46

Slide 46 text

Component Lookup Em.ComponentLookup.lookupFactory var fullName = 'component:' + name, templateFullName = 'template:components/' + name, templateRegistered = this.container && this.container.has(templateFullName); if (templateRegistered) container.injection(fullName, 'layout', templateFullName);

Slide 47

Slide 47 text

Component Lookup Em.ComponentLookup.lookupFactory var Component = container.lookupFactory(fullName); if (templateRegistered || Component) if (!Component) { container.register(fullName, Ember.Component); Component = container.lookupFactory(fullName); }

Slide 48

Slide 48 text

Component Lookup app/components/x-foo.js app/templates/components/x-foo.hbs Files looked up:

Slide 49

Slide 49 text

app/components/x-foo.js app/templates/components/x-foo.hbs Component Lookup Files looked up:

Slide 50

Slide 50 text

Component Lookup app/components/x-foo.js // packages/ember-handlebars/lib/component_lookup.js#L16 // Ember.ComponentLookup#lookupFactory var Component = container.lookupFactory(fullName);

Slide 51

Slide 51 text

Component Lookup app/components/x-foo.js app/templates/components/x-foo.hbs Files looked up:

Slide 52

Slide 52 text

Component Lookup app/templates/components/x-foo.hbs // packages/ember-handlebars/lib/component_lookup.js#L13 // Ember.ComponentLookup#lookupFactory templateFullName = 'template:components/' + name; container.injection(fullName, 'layout', templateFullName);

Slide 53

Slide 53 text

Magic?

Slide 54

Slide 54 text

Nope, Just Javascript