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.
- Ember Octane
- My Octane preview video (slightly out of date, MU mainly)
- Chris Garret’s series:
These are the steps that I'll follow while demonstrating the Octane preview:
- Please feel free to ask questions at any point
-
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
-
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
- ember g component button
- ember g component counter
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;
}
}
- 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',
});
becomes:
- @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
- ember g service global-count
- Add a second button which invoked service increment action
- @ember/render-modifiers
.grow {
animation: growAnimation 1s;
}
@keyframes growAnimation {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
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');
}
}
-
ember new octane-dublin -b @ember/octane-app-blueprint
-
cd octane-dublin
-
ember g component Counter
-
ember serve
- open http://localhost:4200