Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Ember & Ember CLI

Intro to Ember & Ember CLI

From the April 2015 EmberATX meetup in Austin, TX.

tehviking

April 24, 2015
Tweet

More Decks by tehviking

Other Decks in Programming

Transcript

  1. w e l c o m e t o t

    h e n e x t l e v e l
  2. Ember CLI: UP AND RUNNING! The stuff you need to

    build next-level native web apps
  3. WHAT WE’LL COVER: ¶ Ember CLI basics ¶ Building an

    app with CLI ¶ Migrating to Ember-CLI
  4. Ember lets me focus on our unique business problems, not

    boilerplate code i just wanna code!
  5. Let’s see, we have a community, a shared problem, and

    Ember philosophy... so what do we do?
  6. “You should begin moving your app to Ember CLI as

    soon as possible.” - Tom Dale, Javascript Ombudsman WHY ember cli?
  7. So let’s get up to speed. And get back to

    what we like: making stuff.
  8. the pleasure º Generators º Fast builds º Add-on ecosystem

    º Testing integration º ES6, Sass support
  9. THE PAIN ‡ Learning ES6 modules ‡ Cryptic error messages

    like “cannot find file tmp/3n8glcv7cv6sgs ‡ Migrating existing apps to Ember-CLI
  10. basic concepts - Installing - Generating - Using ES6 modules

    - Folder structure - Assets - Testing - Deployment
  11. LMGTFY ember generate route images ember generate component pixelate-image and

    my favorite... ember generate acceptance-test images (...let me generate that for you)
  12. Ember GENERATORS Controller Model Route Resource Template Mixin Component Helper

    Initializer Adapter Serializer Service Transform Util View
  13. Ember GENERATORS Acceptance-test* Adapter-test Component-test Controller-test Helper-test Initializer-test Mixin-test Model-test

    Route-test Serializer-test Service-test Transform-test Util-test View-test *(All but this are generated automatically)
  14. Ember GENERATORS Addon In-repo-addon (& lib) App Blueprint Http-mock Http-proxy

    Server Test-helper Plus custom generators from installed addons ...Or create your own
  15. App.ImagesRoute = Ember.Route.extend({
 model: function() {
 return App.imageData();
 }
 });

    app/routes/images-route.js From globals... Ember is global imageData comes from global App (at least, we hope)
  16. import Ember from 'ember';
 import imageData from '../utils/image-data';
 
 var

    ImagesRoute = Ember.Route.extend({
 model: function() {
 return imageData();
 }
 }); export default ImagesRoute; app/routes/images.js TO ES6 Modules
  17. import Ember from 'ember';
 import imageData from '../utils/image-data';
 
 var

    ImagesRoute = Ember.Route.extend({
 model: function() {
 return imageData();
 }
 }); export default ImagesRoute; app/routes/images.js to ES6 Modules Ember comes from ember.js
  18. import Ember from 'ember';
 import imageData from '../utils/image-data';
 
 var

    ImagesRoute = Ember.Route.extend({
 model: function() {
 return imageData();
 }
 }); export default ImagesRoute; app/routes/images.js to ES6 Modules imageData comes from ../utils
  19. import Ember from 'ember';
 import imageData from '../utils/image-data';
 
 var

    ImagesRoute = Ember.Route.extend({
 model: function() {
 return imageData();
 }
 }); export default ImagesRoute; app/routes/images.js to ES6 Modules export so others can import
  20. ember generate resource foo --pod and if you want, in

    your env: podModulePrefix: 'pixelfy-me/pods' Maybe you’ll like it
  21. ApplicationRoute (generated): ‘/’ ProductRoute: ‘/:id’ Rendered into products {{outlet}} URL:

    / products / 230 ProductsRoute: ‘/products’ Rendered into application {{outlet}}
  22. COMPUTED PROPERTIES app/controllers/cart.js export default Ember.Controller.extend({
 cartItemSubtotals: Ember.computed.mapBy("model.cartItems", "subtotal"),
 orderSubtotal:

    Ember.computed.sum("cartItemSubtotals"),
 shippingCost: Ember.computed(function() {
 return 0;
 }),
 orderTax: Ember.computed("orderSubtotal", function() {
 var taxCents = (this.get("orderSubtotal") * 100) * 0.0825;
 return taxCents / 100;
 }),
 orderTotal: Ember.computed("orderTax", "orderSubtotal", function() {
 return this.get("orderSubtotal") + this.get("orderTax");
 }),
 });
  23. COMPUTED MACROS app/controllers/cart.js export default Ember.Controller.extend({
 cartItemSubtotals: Ember.computed.mapBy("model.cartItems", "subtotal"),
 orderSubtotal:

    Ember.computed.sum("cartItemSubtotals"),
 shippingCost: Ember.computed(function() {
 return 0;
 }),
 orderTax: Ember.computed("orderSubtotal", function() {
 var taxCents = (this.get("orderSubtotal") * 100) * 0.0825;
 return taxCents / 100;
 }),
 orderTotal: Ember.computed("orderTax", "orderSubtotal", function() {
 return this.get("orderSubtotal") + this.get("orderTax");
 }),
 });
  24. IF YOU UNDERSTAND: • Generating with Ember CLI • Router

    & Routes • Components • Computed Properties YOU CAN BUILD AWESOME STUFF
  25. Ember CLI lets me focus on our unique business problems,

    not janky build systems i just wanna code!
  26. Let’s build an app! ember new pixelfy-me cd pixelfy-me git

    remote add origin https://github.com/thefrontside/pixelfy-me.git git fetch --tags open the folder in your text editor of choice
  27. Task 1: List Images What we’ll do: Generate Images resource

    Write Model hook for Images Route Install helper for image data Display images on Images page
  28. git checkout task-1 npm install bower install (Stuck? You can

    git checkout at any task with git checkout task-<task number>) Task 1: List Images
  29. import Ember from 'ember';
 
 export default Ember.Route.extend({
 model: function()

    {
 return imageData();
 }
 });
 
 app/routes/images.js Load data in model hook KABOOOOOM! (doesn’t exist)
  30. import Ember from 'ember'; import imageData from 'ember-cli-sample-image-data';
 
 export

    default Ember.Route.extend({
 model: function() {
 return imageData();
 }
 });
 
 app/routes/images.js import it in the route
  31. ... "8": {
 id: "8",
 url: "/img/yeezus.jpg"
 }
 };
 if(arguments.length)

    {
 return Image.create(images[id]);
 } else {
 var imagesArray = Object.keys(images).map(function(k){
 return Image.create(images[k]);
 });
 return imagesArray;
 }
 inside the addon’s hidden volcano lair... P.S. it’s not really that magical
  32. Let’s talk about what just happened: - Generated a route

    & model - Tweaked the route & model slightly - Installed an addon - Used ES6 to include the addon helper That loads images!
  33. task 2: show image What we’ll do: Generate images/show route

    Add dynamic segment to show route Write Model hook for Images Show Route Link to Image from Images page Display image on Image Show section
  34. import Ember from 'ember';
 import imageData from 'ember-cli-sample-image-data';
 
 export

    default Ember.Route.extend({
 model: function(params) {
 return imageData(params.id);
 }
 }); app/routes/images/show.js Add model hook & import statement
  35. {{#each image in model}}
 <li>
 {{#link-to "images.show" image}}
 <img class="gallery-image"

    src={{image.url}}>
 {{/link-to}}
 </li>
 {{/each}}
 app/templates/images.hbs link to image from images template
  36. <div class="row">
 <div class="col-md-12">
 <img src={{model.url}}>
 <!-- Insert the pixelate-image

    component, bind src to model.url, bind value to pixelatePercentage -->
 ! Implement pixelate-image here !
 </div>
 </div>
 app/templates/images/show.hbs Display image in the show template
  37. To recap what we just built: - Generated a nested

    route with / - Used a dynamic segment - Re-used ES6 for our imageData helper - Edited template files to display stuff images/show done!
  38. task 3: pixelatE What we’ll do: Install pixelate-image component Wrap

    image in pixelate component Install {{emberx-slider}} component Drop in {{x-slider}} component
  39. Let’s look at what we did: - Installed pixelate-image custom

    addon - Installed emberx-slider addon - Tied the two together to make MAGIC So yeah
  40. task 4: Style it What we’ll do: Install ember-cli-sass addon

    Install bootstrap-sass bower package rename app.css to app.scss include bootstrap include custom SCSS
  41. COPY & PASTE CSS FILES Files are here (grab the

    tar file): http://bit.ly/cli-training-styles - app.scss - _bootswatch.scss - bootstrap_imports.scss - bootstrap_variables.scss Copy or move them to app/styles
  42. Now we have a fully styled app! - Installed ember-cli-sass

    to compile Sass - Installed bootstrap-sass - Used Sass @include for granular control so stylin’
  43. task 5: test it Add karma, karma-cil, karma-mocha, karma-chai- plugins,

    karma-chrome-launcher, karma-ember- preprocessor, karma-mocha, karma-phantomjs- launcher, karma-junit-reporter to package.json Compile and install PhantomJS npm install Install ember-mocha-adapter and chai-jquery via Bower Set up a karma.conf file In your karma.conf: Customize your frameworks section in karma.conf to include mocha, chai, sinon-chai, and chai-jquery Set up a Grunt task to build your Sass on each test run Include your vendor dependencies in karma.conf Include your code in files section Debug file load order issues Add & configure handlebars karma preprocessor Then, create test-helper.js & include it in karma.conf In your test-helper.js: Configure chai and mocha defaults Set Ember.testing to true Set App.setupForTesting to true Call App.injectTestHelpers() Set up app on each test run Tear down app after each test run Ensure beforeEach and afterEach use the run loop Use the .done() callback for async beforeEach What we’ll do:
  44. task 5: test it What we’ll do: Generate “images” acceptance

    test Remove generated Ember Data test Write an assertion Run the tests
  45. bonus: gravatars What we’ll do: git checkout bonus-stage Set up

    gravatar route & link Handle download action install JavaScript-md5 bower component Pixelate images in the gravatar template
  46. downloadImage: function() {
 var link = document.createElement("a");
 var uri =

    Ember.$("img.pixelated-image").attr("src");
 link.download = "pixelfy.png";
 link.href = uri;
 link.click();
 }
 app/routes/gravatar.js handle download image
  47. This was more complicated. - Set up gravatar route -

    Handled download action - Installed bower component - Included lib in Brocfile and .jshintrc - Mixed pixelate and gravatar together It’s done!
  48. Now we can get back to focusing on moving fast

    and shipping, with a better set of tools i just wanna code!