SlideShare a Scribd company logo
EmberJS
BucharestJS
Singalong!
• https://github.com/rusanu/webstore-demo
npm install ember-cli
• The client side framework
• Routing, bidirectional data flow, Observables, Templating engine
• Data management: data store, change tracking, REST adapter, XHR/Ajax, Promises/RSVP
• Dependency injection, services, computed properties
• JS enhancements (ECMA transpiler, EM.Array to make observable arrays etc)
• The server side build
• Build, serve with live update, test, deploy
• Transpile, concat, uglify, source map, jslint
• Blueprints
• Generate model/route/component etc, including tests
• Add-on management
• Is great for starting new projects, no pick and choose, everything is ‘ready’
• Difficult to add EmberJS incrementaly on existing projects
ember new webstore-demo
• Blueprint for an empty app
• Layout page is app/index.html
• Will render the implicit ‘index’ root
route/template
• Create explicit route:
>ember generate route index
• Edit app/templates/index.hbs
• Build, Test, Serve
• Test requires PhantomJS
+---app
| +---components
| +---controllers
| +---helpers
| +---models
| +---routes
| +---styles
| ---templates
| ---components
+---config
+---public
+---tests
| +---helpers
| +---integration
| ---unit
---vendor
ember generate route index
• Routes are mapped to URLs in app/router.js
• index route is for ‘/’ at every level
• app/routes/index.js -> /
• app/routes/sprockets/index.js -> /sprockets/
• Convention app/router.js can declare whatever it pleases
• Dynamic segments: /posts/:post_id
• Implicit Application route: app/routes/application.js
• Implicit app/templates/application.hbs
• {{outlet}} yields the content of the inner template
Ember Inspector
• Chrome extension, add the Ember panel to dev tools
• You can see application, even empty, has default generated
view/controller for the root index route
ember generate model product …
• EmberJS comes with ember-data
• Data store
• Fetches data from sources (back-end)
• Tracks record changes
• Applies changes to back end
• Relashioships: belongsTo, hasMany
• Adapters to negotiate communication back end
• Typically use one of the REST adapters
• Works easiest with JSONApi.org format
• Handles the AJAX part, Promises etc
ember install ember-localstorage-adapter
• Adapters do not necessarily fetch/pull data to a back-end
• Localstorage adapter uses persistent browser Web Storage API
• You can go a long mile front-end side w/o a back-end
• You can use specific adapters for specific model types
• Convention: model named Foo uses adapter named Foo
• Fallback to Application adapter
Routes -> model -> template
• The route model() function returns the model to be rendered
• In app/routes/index.js
model() { return this.store.findAll(‘product’);}
• The store uses the adapter to retrieve all Products
• REST Adapter: GET /products
• Use the inspector, can see that the model is now an Ember.ArrayProxy
content:[]
store:<webstore-demo@service:store::ember394>
isLoaded:true
manager:<(unknown mixin):ember540>
isUpdating:false
Add a product: events and actions
• <button {{action 'addProduct'}}>Add Product</button>
• The addProduct action can be handled by components, controllers, routes
• Add a route to display/handle new product
• ember generate route products/add
• Modify app/routes/index.js to respond to the action:
actions: {
addProduct() {
this.transitionTo('products.add');
}
}
• app/routes/products/add.js
• model() { return this.store.createRecord(‘product’); }
Detour: Style it
ember install ember-cli-sass
ember install ember-cli-bootstrap-sassy
• Rename app/style/app.css to app/style/app.scss and edit it:
@import “bootstrap”;
• There is also ember-paper add-on for Material Design
aficionados
• Will have to do a full build and restart the live reload server
The add product form
• We need to get the DOM #id for labels:
http://stackoverflow.com/a/34664559/105929
• ember generate helper guid-for
• Helpers extend the templating language:
<label for="{{guid-for this "name"}}">
{{input id=(guid-for this "name") value=model.name }}
• Binding to model.name is bidirectional
• We add two buttons and bind them to add and cancel actions
Handle the save and cancel actions
• In app/routes/products/add.js
actions: {
add() {
this.modelFor(this.routeName).save().then(function() {
this.transitionTo('index');
}.bind(this));
},
cancel() {
this.modelFor(this.routeName).rollbackAttributes();
this.transitionTo('index');
}
}
• Notice the bind(this) (ECMA6) and the use of the promise when save to the back end
• this.modelFor(this.routeName) is the usual trick to access model from the route
• BTW Ember Inspector Data will not properly reflect the removal of the product on cancel
ember generate component product-panel
• In app/templates/index.hbs:
{{#each model as |product|}}
{{product-panel product=product}}
{{/each}}
• app/components/product-panel.js
• Components can add behavior, respond to actions
• EmberJS will remove controllers and use routable components instead
• App/templates/components/product-panel.hbs
• A component becomes automatically also a template helper
ember generate service shopping-cart
• EmberJS supports dependency injections, factories, singletons,
initializers and other ‘application concerns’
• A common pattern is service injection: make a ‘service’ easily
available from any part of the application
• In out product-panel.js:
shoppingCart: Ember.inject.service(),
• Makes the shopping cart available w/o having to pass parameters or
reference global
ember test
• Because we’ve been using ember generate blueprints we actually
have a test for every route, model, component, controller, serializer,
adapter helper etc.
• Blueprint tests are basic, but they do exercise the relevant code and
are the starting point for further validations and assertions.
EmberJS
• It fits best with teams, because it enforces a consistent structure
• ember-cli offers blueprints, build, serve, compile
• Because it tries to cover everything, it integrates poorly with other
frameworks
• Excelent documentation and guides at emberjs.com
• Take any EmberJS answer you find on StackOverflow pre 2015 with a
big grain of salt. Anything that predates ember-cli is likely obsolete.
• Handlebar templates are just a tiny part of EmberJS.

More Related Content

EmberJS BucharestJS

  • 3. npm install ember-cli • The client side framework • Routing, bidirectional data flow, Observables, Templating engine • Data management: data store, change tracking, REST adapter, XHR/Ajax, Promises/RSVP • Dependency injection, services, computed properties • JS enhancements (ECMA transpiler, EM.Array to make observable arrays etc) • The server side build • Build, serve with live update, test, deploy • Transpile, concat, uglify, source map, jslint • Blueprints • Generate model/route/component etc, including tests • Add-on management • Is great for starting new projects, no pick and choose, everything is ‘ready’ • Difficult to add EmberJS incrementaly on existing projects
  • 4. ember new webstore-demo • Blueprint for an empty app • Layout page is app/index.html • Will render the implicit ‘index’ root route/template • Create explicit route: >ember generate route index • Edit app/templates/index.hbs • Build, Test, Serve • Test requires PhantomJS +---app | +---components | +---controllers | +---helpers | +---models | +---routes | +---styles | ---templates | ---components +---config +---public +---tests | +---helpers | +---integration | ---unit ---vendor
  • 5. ember generate route index • Routes are mapped to URLs in app/router.js • index route is for ‘/’ at every level • app/routes/index.js -> / • app/routes/sprockets/index.js -> /sprockets/ • Convention app/router.js can declare whatever it pleases • Dynamic segments: /posts/:post_id • Implicit Application route: app/routes/application.js • Implicit app/templates/application.hbs • {{outlet}} yields the content of the inner template
  • 6. Ember Inspector • Chrome extension, add the Ember panel to dev tools • You can see application, even empty, has default generated view/controller for the root index route
  • 7. ember generate model product … • EmberJS comes with ember-data • Data store • Fetches data from sources (back-end) • Tracks record changes • Applies changes to back end • Relashioships: belongsTo, hasMany • Adapters to negotiate communication back end • Typically use one of the REST adapters • Works easiest with JSONApi.org format • Handles the AJAX part, Promises etc
  • 8. ember install ember-localstorage-adapter • Adapters do not necessarily fetch/pull data to a back-end • Localstorage adapter uses persistent browser Web Storage API • You can go a long mile front-end side w/o a back-end • You can use specific adapters for specific model types • Convention: model named Foo uses adapter named Foo • Fallback to Application adapter
  • 9. Routes -> model -> template • The route model() function returns the model to be rendered • In app/routes/index.js model() { return this.store.findAll(‘product’);} • The store uses the adapter to retrieve all Products • REST Adapter: GET /products • Use the inspector, can see that the model is now an Ember.ArrayProxy content:[] store:<webstore-demo@service:store::ember394> isLoaded:true manager:<(unknown mixin):ember540> isUpdating:false
  • 10. Add a product: events and actions • <button {{action 'addProduct'}}>Add Product</button> • The addProduct action can be handled by components, controllers, routes • Add a route to display/handle new product • ember generate route products/add • Modify app/routes/index.js to respond to the action: actions: { addProduct() { this.transitionTo('products.add'); } } • app/routes/products/add.js • model() { return this.store.createRecord(‘product’); }
  • 11. Detour: Style it ember install ember-cli-sass ember install ember-cli-bootstrap-sassy • Rename app/style/app.css to app/style/app.scss and edit it: @import “bootstrap”; • There is also ember-paper add-on for Material Design aficionados • Will have to do a full build and restart the live reload server
  • 12. The add product form • We need to get the DOM #id for labels: http://stackoverflow.com/a/34664559/105929 • ember generate helper guid-for • Helpers extend the templating language: <label for="{{guid-for this "name"}}"> {{input id=(guid-for this "name") value=model.name }} • Binding to model.name is bidirectional • We add two buttons and bind them to add and cancel actions
  • 13. Handle the save and cancel actions • In app/routes/products/add.js actions: { add() { this.modelFor(this.routeName).save().then(function() { this.transitionTo('index'); }.bind(this)); }, cancel() { this.modelFor(this.routeName).rollbackAttributes(); this.transitionTo('index'); } } • Notice the bind(this) (ECMA6) and the use of the promise when save to the back end • this.modelFor(this.routeName) is the usual trick to access model from the route • BTW Ember Inspector Data will not properly reflect the removal of the product on cancel
  • 14. ember generate component product-panel • In app/templates/index.hbs: {{#each model as |product|}} {{product-panel product=product}} {{/each}} • app/components/product-panel.js • Components can add behavior, respond to actions • EmberJS will remove controllers and use routable components instead • App/templates/components/product-panel.hbs • A component becomes automatically also a template helper
  • 15. ember generate service shopping-cart • EmberJS supports dependency injections, factories, singletons, initializers and other ‘application concerns’ • A common pattern is service injection: make a ‘service’ easily available from any part of the application • In out product-panel.js: shoppingCart: Ember.inject.service(), • Makes the shopping cart available w/o having to pass parameters or reference global
  • 16. ember test • Because we’ve been using ember generate blueprints we actually have a test for every route, model, component, controller, serializer, adapter helper etc. • Blueprint tests are basic, but they do exercise the relevant code and are the starting point for further validations and assertions.
  • 17. EmberJS • It fits best with teams, because it enforces a consistent structure • ember-cli offers blueprints, build, serve, compile • Because it tries to cover everything, it integrates poorly with other frameworks • Excelent documentation and guides at emberjs.com • Take any EmberJS answer you find on StackOverflow pre 2015 with a big grain of salt. Anything that predates ember-cli is likely obsolete. • Handlebar templates are just a tiny part of EmberJS.

Editor's Notes

  1. !important clean chrome localstorage rd /q /s dist
  2. git checkout initial
  3. git checkout –f step-1
  4. git checkout –f step-2
  5. Vim e: package.json
  6. Git checkout –f step-3
  7. Stop ember serve (app/styles access race) git checkout –f step-4
  8. git checkout –f step-5
  9. git checkout –f step-6
  10. git checkout –f step-7
  11. git checkout –f step-8