/* * ----------------------- * Ember.js Cheatsheet * ----------------------- * * Docs: https://guides.emberjs.com/ * Quick start: https://guides.emberjs.com/current/getting-started/quick-start/ * * Table of contents * ------------------- * 01 | Installation * 02 | Ember CLI * 03 | Directory layout * 04 | Routes * 05 | Templates * 06 | Components * 07 | Models * 08 | Services * 09 | Testing * 10 | Addons * 11 | Configuration * 12 | Community * */ /* * 01 | Installation * -------------------------------------------------------------- * Getting started with Ember is easy. Ember projects are created * and managed through our command line build tool Ember CLI. */ ``` npm install -g ember-cli ember new ember serve ``` /* * 02 | Ember CLI * -------------------------------------------------------------- * Ember CLI is the Ember.js command line utility that provides a * fast Broccoli-powered asset pipeline, a strong conventional * project structure, and a powerful addon system for extension. * * Among the principal features of Ember CLI are: - Project/Addon creation: create new projects quickly without having to worry about project structure; - Build pipeline: asset compilation, finger-printing and more out of the box; - Generators: use the built-in generators and get files that follow the latest practices, and matching tests; - Ember Addons: extend both your application and Ember CLI itself with community solutions. Also an excellent way to easily integrate 3rd party libraries into your Ember app. */ Basic commands Command | Aliases | Description -------------------------------------------------- ``` ember new | | Create new project with the provided name (ex. ember new ) ember server | ember s | Starts development server (default port is 4200) ember test | ember t | Run tests in CI mode ember generate | ember g | Run generator ember destroy | ember d | Remove code created by generator ember help | ember h | Get more info on available cli command ember install | ember i | Install given addon into project and save to package.json ember | | List available cli commands ``` Useful commands ``` ember s --proxy ember s --port ``` /* * 03 | Directory Layout * -------------------------------------------------------------- * * Layout of the root folder */ app/ ` This is where folders and files for models, components, routes, templates and styles are stored. The majority of your coding on an Ember project happens in this folder. ` config/ ` The config directory contains the environment.js where you can configure settings for your app. ` node_modules/ ` This directory is from npm. npm is the package manager for Node.js. Ember is built with Node and uses a variety of Node.js modules for operation. The package.json file maintains the list of current npm dependencies for the app. Any Ember CLI addons you install will also show up here. ` public/ ` This directory contains assets such as images and fonts. ` vendor/ ` This directory is where front-end dependencies (such as JavaScript or CSS) that are not managed by NPM go. ` tests/testem.js ` Automated tests for our app go in the tests folder, and Ember CLI's test runner testem is configured in testem.js. ` ember-cli-build.js ` This file describes how Ember CLI should build our app. ` package.json ` Packages listed in package.json are installed in the node_modules directory. ` /* * Layout of the app directory */ adapters/ ` Adapters with the convention adapter-name.js. ` components/ ` Components with the convention component-name.js. Components must have a dash in their name. So blog-post is an acceptable name, but post is not. ` controllers/ ` Controllers behave like a specialized type of Component that is rendered by the router when entering a Route. ` helpers/ ` Helpers with the convention helper-name.js. Helpers must have a dash in their name. Remember that you must register your helpers by exporting makeBoundHelper or calling registerBoundHelper explicitly. ` models/ ` Models with the convention model-name.js. ` routes/ ` Routes with the convention route-name.js. Child routes are defined in sub-directories, parent/child.js. To provide a custom implementation for generated routes (equivalent to App.Route when using globals), use app/routes/basic.js. ` styles/ ` Contains your stylesheets, whether SASS, LESS, Stylus, Compass, or plain CSS (though only one type is allowed, see Asset Compilation). These are all compiled into .css. ` templates/ ` Your HTMLBars templates. These are compiled to /dist/assets/.js. The templates are named the same as their filename, minus the extension (i.e. templates/foo/bar.hbs -> foo/bar). ` serializers/ ` Serializers for your models or adapter, where model-name.js or adapter-name.js. ` utils/ ` Utility modules with the convention utility-name.js. ` router.js ` Your route configuration. The routes defined here correspond to routes in app/routes/. ` /* * 03 | Routes * -------------------------------------------------------------- * * When your application starts, the router matches the current URL to the routes that you've defined. * The routes, in turn, are responsible for displaying templates, loading data, and setting up application state. * * > ember g route */ import Route from '@ember/routing/route'; export default Route.extend({ model() { // Typically, the model hook should return an Ember Data record, // but it can also return any promise object (Ember Data records are // promises), or a plain JavaScript object or array. Ember will wait // until the data finishes loading (until the promise is resolved) // before rendering the template. } }); /* * 04 | Templates * -------------------------------------------------------------- * * Ember uses the Handlebars templating library to power your app's user * interface. Handlebars templates contain static HTML and dynamic * content inside Handlebars expressions, which are invoked with * double curly braces: {{}}. * * Templates are backed with a context. A context is an object from * which Handlebars expressions read their properties. In Ember this * is often a component. For templates rendered by a route (like application.hbs), * the context is a controller. * * > ember g template */ // Here's an basic exmpale of a template ```hbs Hello, {{firstName}} {{lastName}}! ``` /* * 05 | Components * -------------------------------------------------------------- * * Ember components are used to encapsulate markup and style into * reusable content. Components consist of two parts: a JavaScript * component file that defines behavior, and its accompanying Handlebars * template that defines the markup for the component's UI. * * > ember g component */ // app/components/.js import Component from '@ember/component'; export default Component.extend({ }); // app/templates/components/.hbs ```hbs {{yield}} ``` /* * Actions * * Provide a means to communicate events and changes */ // app/components/rental-listing.js import Component from '@ember/component'; export default Component.extend({ isWide: false, actions: { toggleImageSize() { this.toggleProperty('isWide'); } } }); // Actions can be attached to DOM elements inside templates using the {{action}} helper ``` app/templates/components/rental-listing.hbs ``` /* * Component lifecycle * * As components are rendered, re-rendered and finally removed, Ember provides * lifecycle hooks that allow you to run code at specific times in a component's life. */ On Initial Render 1 init 2 didReceiveAttrs 3 willRender 4 didInsertElement // Good place to integrate with 3rd party libraries 5 didRender On Re-Render 1 didUpdateAttrs 2 didReceiveAttrs 3 willUpdate 4 willRender 5 didUpdate 6 didRender On Component Destroy 1 willDestroyElement 2 willClearRender 2 didDestroyElement /* * Block params * * Components can have properties passed in, but they can also return * output to be used in a block expression. */ // Here an entire blog post model is being passed to the component as a // single component property. In turn the component is returning values using yield. ``` app/templates/index.hbs {{blog-post post=model}} ``` ``` app/templates/components/blog-post.hbs {{yield post.title post.body post.author}} ``` // The block expression can then use block params to bind names to any yielded // values for use in the block. This allows for template customization when using // a component, where the markup is provided by the consuming template, but any // event handling behavior implemented in the component is retained such as click() handlers. ``` app/templates/index.hbs {{#blog-post post=model as |title body author|}}

{{title}}

by {{author}}

{{body}}

{{/blog-post}} ``` // The names are bound in the order that they are passed to yield in the component template. /* * 06 | Models * -------------------------------------------------------------- * * Models are objects that represent the underlying data that your application * presents to the user. Different apps will have very different models, * depending on what problems they're trying to solve. * * Ember Data, included by default when you create a new application, * is a library that integrates tightly with Ember to make it easy to * retrieve models from your server as JSON, save updates back to the server, * and create new models in the browser. * * > ember g model */ import DS from 'ember-data'; import { computed } from '@ember/object'; const { attr, Model } = DS; export default Model.extend({ firstName: attr('string'), lastName: attr('string'), birthday: attr('date'), // Computed properties // These are effectively fuctions declared as properties. The function's result // will recompute every time one of the provided 'dependent keys' changes. fullName: computed('firstName', 'lastName', function() { let firstName = this.get('firstName'); let lastName = this.get('lastName'); return `${firstName} ${lastName}`; }) }); /* * 07 | Services * -------------------------------------------------------------- * * A Service is an Ember object that lives for the duration of the application, and can * be made available in different parts of your application. Services are useful for * features that require shared state or persistent connections. * * Example uses of services might include: * * - User/session authentication. * - Geolocation. * - WebSockets. * - Server-sent events or notifications. * - Server-backed API calls that may not fit Ember Data. * - Third-party APIs. * - Logging. * * > ember g service */ /* * Defining services * * Like any Ember object, a service is initialized and can have properties and * methods of its own. Below, the shopping cart service manages an items array * that represents the items currently in the shopping cart. */ // app/services/shopping-cart.js import Service from '@ember/service'; export default Service.extend({ items: null, init() { this._super(...arguments); this.set('items', []); }, remove(item) { this.get('items').removeObject(item); } }); /* * Accessing services * * To access a service, you can inject it in any object such as a component or another * service using the `inject` function from the `@ember/service` module. */ // app/components/cart-contents.js import Component from '@ember/component'; import { inject } from '@ember/service'; export default Component.extend({ shoppingCart: inject() // will load the service in file /app/services/shopping-cart.js actions: { remove(item) { this.get('shoppingCart').remove(item); } } }); // Once injected into a component, a service can also be used in the template. // Note cart being used below to get data from the cart. ```hbs app/templates/components/cart-contents.hbs
    {{#each cart.items as |item|}}
  • {{item.name}}
  • {{/each}}
``` /* * 08 | Testing * -------------------------------------------------------------- * * Testing is a core part of the Ember framework and its development cycle. * * > ember g acceptance-test * > ember g integration-test * > ember g unit-test * > ember t --server * > ember s && visit localhost:4200/tests */ /* * Acceptance & application tests * * In these kinds of tests, we interact with the application in the same ways that a * user would, such as filling out form fields and clicking buttons. Application * tests ensure that the interactions within a project are basically functional, the * core features of a project have not regressed, and the project's goals are being met. * * Some useful helpers from '@ember/test-helpers': * - `click(selector)` * Clicks an element and triggers any actions triggered by the element's click event and * returns a promise that fulfills when all resulting async behavior is complete. * * - `fillIn(selector, value)` * Fills in the selected input with the given value and returns a promise that * fulfills when all resulting async behavior is complete. Works with elements. Keep in mind that with