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

Intro to Ember.js and Ember-CLI - Front Porch 2015

Intro to Ember.js and Ember-CLI - Front Porch 2015

Introduction to Ember.js and Ember-CLI given at Front Porch Conf in Dallas.

Iheanyi Ekechukwu

October 20, 2015
Tweet

More Decks by Iheanyi Ekechukwu

Other Decks in Programming

Transcript

  1. Ember.js & Ember-CLI
    Iheanyi Ekechukwu
    @kwuchu
    IBM Watson Life
    http://iheanyi.com

    View Slide

  2. What is Ember?

    View Slide

  3. A framework for
    creating ambitious
    web applications.

    View Slide

  4. Why Ember?

    View Slide

  5. As a Designer

    View Slide

  6. I can make ambitious UIs.
    Like, really ambitious.

    View Slide

  7. View Slide

  8. View Slide

  9. Let's see another
    "ambitious" UI

    View Slide

  10. View Slide

  11. How is this possible?

    View Slide

  12. View Slide

  13. Just kidding.
    Ember's Router and Nested Routes = <3
    Data, URLs, UI, and State are all in sync.

    View Slide

  14. import Ember from 'ember';
    import config from './config/environment';
    var Router = Ember.Router.extend({
    location: config.locationType
    });
    export default Router.map(function() {
    this.route('contacts', function() {
    this.route('show', {path: '/:id'});
    });
    });

    View Slide

  15. URL:t
    URL: /contacts/1

    View Slide

  16. Animations help
    take your UI to the
    next level.

    View Slide

  17. Liquid Fire
    (https://github.com/ef4/liquid-
    fire)

    View Slide

  18. Gif of Barbr here.

    View Slide

  19. Wow, that must've been
    really complicated.

    View Slide

  20. ember install liquid-fire

    View Slide

  21. {{liquid-outlet}} # previously {{outlet}}



    {{#link-to 'index' class="navbar-brand"}}
    Barber Application
    {{/link-to}}


    {{link-to 'Barbershops' 'barbershops'}}


    {{#if this.currentUser}}
    Signed in as {{currentUser.username}}
    Logout
    {{else}}
    {{link-to "Login" 'login'}}
    {{link-to 'Register' 'users.new'}}
    {{/if}}



    View Slide

  22. export default function() {
    this.transition(
    this.fromRoute('index'),
    this.use('toLeft'),
    this.reverse('toRight')
    );
    this.transition(
    this.fromRoute('barbershops'),
    this.use('toLeft'),
    this.reverse('toRight')
    );
    }

    View Slide

  23. View Slide

  24. As a Developer

    View Slide

  25. Convention over
    Configuration.

    View Slide

  26. HTMLBars for
    Templating

    View Slide

  27. Simple Template Action
    Handling by Components,
    Controllers, and Routes

    View Slide

  28. View Slide


  29. Sign In With Facebook

    {{/if}}
    {{#if session.isAuthenticated}}
    'invalidateSession'}}>
    Logout

    {{else}}

    View Slide

  30. import Ember from 'ember';
    import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
    export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:torii',
    actions: {
    signIn: function() {
    var controller = this.controllerFor('index');
    var session = this.get('session');
    session.authenticate('simple-auth-authenticator:torii', 'facebook-
    connect').then(function() {
    controller.transitionToRoute('likes');
    });
    }
    });

    View Slide

  31. View Slide

  32. Ember-Data

    View Slide

  33. Let's see a quick
    example/overview.

    View Slide

  34. ember generate adapter application
    create app/adapters/application
    create tests/unit/adapters/application-test.js

    View Slide

  35. import DS from 'ember-data';
    export default DS.RESTAdapter.extend({
    namespace: 'api'
    });

    View Slide

  36. ember generate model contact firstName:string lastName:string \
    email:string avatar:string description:string
    create app/models/contact.js
    create tests/unit/models/contacts-test.js

    View Slide

  37. // app/models/contact.js
    import DS from 'ember-data';
    export default DS.Model.extend({
    firstName: DS.attr('string'),
    lastName: DS.attr('string'),
    avatar: DS.attr('string'),
    email: DS.attr('string'),
    description: DS.attr('string')
    });

    View Slide

  38. ember generate route contacts
    create app/routes/contacts.js
    create tests/unit/routes/contacts-test.js

    View Slide

  39. // app/routes/contacts.js
    import Ember from 'ember';
    export default Ember.Route.extend({
    });

    View Slide

  40. // app/routes/contacts.js
    import Ember from 'ember';
    export default Ember.Route.extend({
    model() {
    return this.store.findAll('contact');
    }
    });

    View Slide

  41. this.store.findAll('contact');

    View Slide

  42. this.store.findRecord('contact', params.id);

    View Slide

  43. this.store.createRecord('contact', data);

    View Slide

  44. this.store.query('contact', query);

    View Slide

  45. this.store.findRecord('contact', params.id).then(function(contact) {
    contact.set('firstName', 'Iheanyi');
    contact.save();
    });
    }

    View Slide

  46. contact.deleteRecord();

    View Slide

  47. contact.destroyRecord();

    View Slide

  48. Computed Properties

    View Slide

  49. // app/models/contact.js
    import DS from 'ember-data';
    export default DS.Model.extend({
    firstName: DS.attr('string'),
    lastName: DS.attr('string'),
    avatar: DS.attr('string'),
    email: DS.attr('string'),
    description: DS.attr('string'),
    fullName: Ember.computed('firstName', 'lastName', function(key, value) {
    return `${this.get('firstName')} ${this.get('lastName')}`;
    })
    });

    View Slide

  50. this.store.createRecord('contact', {firstName: "Iheanyi", lastName:
    "Ekechukwu"}).then(function(contact) {
    contact.get('fullName'); // Iheanyi Ekechukwu
    });

    View Slide

  51. import Ember from 'ember';
    export default Ember.Controller.extend({
    sortProperties: ['fullName'],
    sortedContacts: Ember.computed.sort('model', 'sortProperties')
    });

    View Slide

  52. Bound Attributes

    View Slide

  53. E-Mail: {{model.email}}

    View Slide

  54. Components for Reusability

    View Slide

  55. ember generate component contact-card
    create app/components/contact-card.js
    create app/templates/components/contact-card.hbs
    installing component-test
    create tests/integration/components/contact-card-test.js

    View Slide


  56. {{contact.fullName}}
    {{contact.description}}

    {{yield}}

    View Slide

  57. {{contact-card contact=model}}

    View Slide

  58. Community

    View Slide

  59. Community

    View Slide

  60. Ember Community Slack Channel
    (https://ember-community-
    slackin.herokuapp.com/)

    View Slide

  61. Tooling

    View Slide

  62. Ember-Inspector
    (https://github.com/
    emberjs/ember-inspector)

    View Slide

  63. View Slide

  64. View Slide

  65. Let's talk more about Ember-
    CLI
    (www.ember-cli.com)

    View Slide

  66. What's the hype
    around Ember-CLI?

    View Slide

  67. ES6

    View Slide

  68. View Slide

  69. But Iheanyi, what about
    third party libraries or
    preprocessors?

    View Slide

  70. bower install bootstrap --save

    View Slide

  71. // ember-cli-build.js
    var EmberApp = require('ember-cli/lib/broccoli/ember-app');
    module.exports = function(defaults) {
    var app = new EmberApp(defaults, {
    // Add options here
    });
    app.import('bower_components/bootstrap/dist/css/bootstrap.css');
    return app.toTree();
    };

    View Slide

  72. Cool! What about for
    JavaScript libraries?

    View Slide

  73. bower install moment --save

    View Slide

  74. // ember-cli-build.js
    var EmberApp = require('ember-cli/lib/broccoli/ember-app');
    module.exports = function(defaults) {
    var app = new EmberApp(defaults, {
    // Add options here
    });
    ...
    app.import('bower_components/moment/moment.js');
    return app.toTree();
    };

    View Slide

  75. And
    preprocessors?

    View Slide

  76. ember install ember-cli-sass
    mv app/styles/app.css app/styles/app.scss

    View Slide

  77. View Slide

  78. RemEMBER those
    conventions?

    View Slide

  79. Generators

    View Slide

  80. ember generate [options] [properties]

    View Slide

  81. acceptance-test
    adapter
    adapter-test
    addon
    addon-import
    app
    blueprint
    component
    component-addon
    component-test
    controller
    controller-test
    helper
    helper-test
    http-mock
    http-proxy
    in-repo-addon
    initializer
    initializer-test
    lib
    mixin
    mixin-test
    model
    model-test
    resource
    route
    route-test
    serializer
    serializer-test
    server
    service
    service-test
    template
    test-helper
    transform
    transform-test
    util
    util-test
    view
    view-test

    View Slide

  82. Addons

    View Slide

  83. Ember Observer
    (http://emberobserver.com/)

    View Slide

  84. View Slide

  85. There's an addon for almost
    everything.

    View Slide

  86. User Authentication?

    View Slide

  87. View Slide

  88. Mock Data/API Services?

    View Slide

  89. View Slide

  90. // app/mirage/factories/contact.js
    import Mirage, {faker} from 'ember-cli-mirage';
    export default Mirage.Factory.extend({
    firstName: faker.name.firstName,
    lastName: faker.name.lastName,
    email: faker.internet.email,
    avatar: faker.internet.avatar,
    description: faker.lorem.paragraphs(4)
    });

    View Slide

  91. // app/mirage/config.js
    export default function() {
    this.namespace = '/api';
    this.get('/contacts', function(db, request) {
    return {contacts: db.contacts};
    });
    this.get('/contacts/:id', function(db, request) {
    return {contacts: db.contacts.find(request.params.id)};
    });
    }

    View Slide

  92. // app/mirage/scenarios/default.js
    export default function( server ) {
    // Seed your development database using your factories. This
    // data will not be loaded in your tests.
    server.createList('contact', 10);
    }

    View Slide

  93. // app/routes/contacts.js
    import Ember from 'ember';
    export default Ember.Route.extend({
    model() {
    return this.store.findAll('contact');
    }
    });

    View Slide


  94. Contacts Route


    {{#each sortedContacts as |contact|}}

    {{#link-to 'contacts.show' contact.id}}


    {{contact.fullName}}

    {{/link-to}}

    {{/each}}



    {{outlet}}


    View Slide

  95. View Slide

  96. Testing

    View Slide

  97. QUnit

    View Slide

  98. ember generate acceptance-test list-contacts

    View Slide

  99. import Ember from 'ember';
    import {
    module,
    test
    } from 'qunit';
    import startApp from 'front-porch-demo/tests/helpers/start-app';
    var application;
    module('Acceptance: ListContacts', {
    beforeEach: function() {
    application = startApp();
    },
    afterEach: function() {
    Ember.run(application, 'destroy');
    }
    });
    test('visiting /contacts should list 10 contacts', function(assert) {
    server.createList('contact', 10); // Thanks Mirage!
    visit('/contacts');
    andThen(function() {
    assert.equal(find('.contacts__list__item').length, 10);
    });
    });

    View Slide

  100. View Slide

  101. Like Mocha? No problem.

    View Slide

  102. ember install ember-cli-mocha

    View Slide

  103. /* jshint expr:true */
    import {
    describe,
    it,
    beforeEach,
    afterEach
    } from 'mocha';
    import { expect } from 'chai';
    import Ember from 'ember';
    import startApp from '../helpers/start-app';
    describe('Acceptance: ListContacts', function() {
    var application;
    beforeEach(function() {
    application = startApp();
    });
    afterEach(function() {
    Ember.run(application, 'destroy');
    });
    it('can visit /contacts and see 10 contacts', function() {
    server.createList('contact', 10);
    visit('/contacts');
    andThen(function() {
    expect(currentPath()).to.equal('contacts.index');
    expect(find('.contacts__list__item').length).to.equal(10);
    });
    });
    });

    View Slide

  104. View Slide

  105. Just wanna test from the
    CLI? Ember-CLI has your
    back.

    View Slide

  106. ember test

    View Slide

  107. ember test
    ...
    1..32
    # tests 32
    # pass 24
    # fail 8

    View Slide

  108. ember test --server

    View Slide

  109. Deploying

    View Slide

  110. View Slide

  111. Adapters for Azure,
    Redis, and S3

    View Slide

  112. npm install ember-cli-deploy --save-dev

    View Slide

  113. ember deploy --environment production

    View Slide

  114. Firebase

    View Slide

  115. View Slide

  116. npm install -g firebase-tools

    View Slide

  117. firebase init

    View Slide

  118. firebase deploy

    View Slide

  119. Trying to deploy to
    Heroku or IBM Bluemix?

    View Slide

  120. There's a buildpack for that.
    (https://github.com/tonycoco/
    heroku-buildpack-ember-cli)

    View Slide

  121. heroku create --buildpack https://github.com/tonycoco/heroku-buildpack-ember-cli.git

    View Slide

  122. cf push ember_contacts_demo -b \
    https://github.com/tonycoco/heroku-buildpack-ember-cli.git

    View Slide

  123. All of these deployment methods run
    the Ember Build command prior to
    deployment.

    View Slide

  124. Getting started with
    Ember-CLI is easy
    enough.

    View Slide

  125. npm install -g ember-cli

    View Slide

  126. ember new ember-demo-project

    View Slide

  127. Now you're ready to dive in.

    View Slide

  128. Links and Thanks
    http://emberjs.com
    http://ember-cli.com
    Brandon (@tehviking)
    Stanley (@fivetanley)
    Lon (@lawnsea)
    Chan (@chantastic)
    Ember Core Team
    And everybody else.

    View Slide

  129. Thank You.
    @kwuchu

    View Slide