Skip to content

Instantly share code, notes, and snippets.

@GavinJoyce
Last active October 11, 2019 07:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GavinJoyce/896f5c5b2c9c2ad54790aceb2e1dbae5 to your computer and use it in GitHub Desktop.
Save GavinJoyce/896f5c5b2c9c2ad54790aceb2e1dbae5 to your computer and use it in GitHub Desktop.

These are some notes for the Ember Dublin March 2019 meet up. This hist can be found at http://bit.ly/octane-dublin.

Node 8+ is recommended for the workshop, as is the latest version of ember-cli.

Useful links:

These are the steps that I'll follow while demonstrating the Octane preview:

Intro

  • Please feel free to ask questions at any point

Create an Octane app:

  • ember new octane-dublin -b @ember/octane-app-blueprint
  • ember serve (you should see Welcome screen)
  • look at package.json
    • canary everything
    • @glimmer/component
    • ember-import
  • optional-features.json
  • Not MU
  • Replace welcome screen

Run some blueprints:

  • ember install ember-cli-tailwind @ember/render-modifiers
  • ember g route people
  • ember g route people/person
  • Classes are native, not EmberObject
    • The only class in Ember that’s not supported is classic components from @ember/component.You can use ember-decorators if needed
  • Create a counter component
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

export default class CounterComponent extends Component {
 @tracked count;

 @action
 increment() {
   this.count++;
 }

 get doubleCount() {
   return this.count * 2;
 }
}
<button onclick={{this.increment}}>
  The count is {{this.count}} (x2 = {{this.doubleCount}})
</button>

Glimmer components

  • Outer vs inner html (no classNames, classNameBindings, tagName etc.)
// app/templates/hello-button.js
import Component from '@ember/component';

export default Component.extend({
 tagName: 'button',
 classNames: ['btn'],
 attributeBindings: ['role'],
 role: 'button',
});
<!-- app/templates/components/hello-button.hbs -->
Hello, world!

becomes:

<!-- app/templates/components/hello-button.hbs -->
<button class="btn" role="button">
	Hello, world!
</button>
  • @action decorator
  • @tracked decorator
  • No get, set
  • args immutable - a codification of DDAU
  • Runloop is hidden
    • Import delay from ‘delay’;
  • Derived state with getters / no computed properties
  • Can be mixed with computed properties
  • Mutations to arrays/objects require the root value to be reset
  • Component lifecycle
    • 2 hooks: constructor & willDestroy (vs 13 in classic)
    • 3 props: args, isDestroying & isDestroyed (vs 50 in classic - 29 event handlers, 9 element properties, 21 functions)
    • Constructor instead of init
    • Fields vs properties (no more issues with objects/arrays being shared)
    • render-modifiers
  • Strict mode: this.property, @argument
  • Component invocation: <Button> vs {{x-button}}
    • just an invocation syntax, works with classic and glimmer components
    • Single word components
    • <Nested::Component />
    • No positional arguments, just named
  • ...attributes

Other things

.grow {
 animation: growAnimation 1s;
}

@keyframes growAnimation {
 from {
   transform: scale(0);
 }
 to {
   transform: scale(1);
 }
}
<div {{did-insert this.didInsert}}>hello</div>
async didInsert(element) {
  await delay(1000);
  element.classList.add('grow');
}
  • In progress RFCs:

  • Routes/models

    • ember g model person
    • @attr() name;
    • ember g route application - seed some data:
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class ApplicationRoute extends Route {
 @service store;

 beforeModel() {
   this.store.createRecord('person', { id: 1, name: 'Alex' });
   this.store.createRecord('person', { id: 2, name: 'Ben' });
   this.store.createRecord('person', { id: 3, name: 'Sophie' });
 }
}
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class PeopleRoute extends Route {
 @service store;

 model() {
   return this.store.peekAll('person');
 }
}
<LinkTo @route="people.person" @model={{person}}>
 {{person.name}}
</LinkTo>

Workshop:

  • ember new octane-dublin -b @ember/octane-app-blueprint
  • cd octane-dublin
  • ember g component Counter
  • ember serve
  • open http://localhost:4200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment