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

What's new in Ember Octane

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

What's new in Ember Octane

Avatar for Yuvaraja

Yuvaraja

March 23, 2019
Tweet

Other Decks in Programming

Transcript

  1. TLDR; ➤ Native Classes (+ Decorators) ➤ Angle Brackets &

    Named arguments ➤ Tracked Properties ➤ Modifiers ➤ Glimmer Components ➤ No jQuery
  2. WHAT ARE EMBER EDITIONS? ➤ SemVer - Major, Minor and

    Patch versions ➤ Like a new major version ➤ Show off that all “new features” in the pipeline has landed
  3. ES6 CLASS SYNTAX class Rectangle { // Class fields height

    = 0; width; constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } } const square = new Rectangle(10, 25); console.log(`The area of Rectangle of dimension \n ${square.width}x${square.height} is: ${square.area}`); // 250
  4. MAIN COMPONENTS ➤ Class Fields - Stage 3 in TC39

    process ➤ Getters ➤ Methods ➤ Inheritance (extends) ➤ Decorators - Stage 2 in TC39 process
  5. “In object-oriented programming, the decorator pattern (also known as Wrapper,

    an alternative naming shared with the Adapter pattern) is a design pattern that allows behaviour to be added to an individual object, either statically or dynamically, without affecting the behaviour of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. -Wikipedia WHAT IS THE DECORATOR PATTERN?
  6. @readonly DECORATOR function readonly(target, name, descriptor) { descriptor.writable = false;

    return descriptor; } class Job { @readonly title() { return 'CEO' } }
  7. BEFORE & AFTER // A person class defined with current

    class syntax import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Steve', lastName: 'Rogers', fullName: computed('firstName', 'lastName', function() { return `${this.firstName} ${this.lastName}`; }), updateName(firstName, lastName) { this.set('firstName', firstName); this.set('lastName', lastName); }, }); // Make an instance of the class, overriding default values Person.create({ firstName: 'Jean', lastName: 'Gray' }); // A person class defined with the new class syntax import EmberObject, { computed } from '@ember/object'; class Person extends EmberObject { firstName = 'Steve'; lastName = 'Rogers'; @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; } updateName(firstName, lastName) { this.set('firstName', firstName); this.set('lastName', lastName); } } // Make an instance of the class, overriding default values Person.create({ firstName: 'Jean', lastName: 'Gray' });
  8. NATIVE EMBER DECORATORS ➤ is now a decorator ➤ All

    computed macros like , , , etc. are all decorators ➤ is now a decorator ➤ is also a decorator Computed lte gte alias inject action
  9. WHAT’S IN IT FOR THE COMMUNITY? ➤ Speed and performance

    enhancements ➤ Shared documentation and tooling ➤ Statically analysed by IDEs, type-checkers (like Flow, Typescript) and documentation generators (like ESDoc) ➤ Classes are first class citizens in Javascript *pun intended*
  10. SYNTAX <!-- Before --> {{#todo-list as |item|}} {{to-do item=item}} {{/todo-list}}

    <!-- After --> <TodoList as |item|> <Todo @item={{item}}/> </TodoList>
  11. NAMED ARGUMENTS <!-- main.hbs --> Hello, {{join (capitalize firstName) (capitalize

    lastName)}}! {{#if (gt todos.length 0)}} <TodoList role="list" @todos={{todos}} as |Item index|> {{add index 1}}. <Item/> </TodoList> {{else}} No todos! {{/if}} <!-- todo-list.hbs --> <ul> {{#each @todos as |todo index|}} <li> {{yield (todo-item-component todo=todo) index}} </li> {{/each}} </ul>
  12. COMPONENTS OWN ATTRIBUTES <!-- main.hbs --> Hello, {{join (capitalize this.firstName)

    (capitalize this.lastName)}}! {{#if (gt this.todos.length 0)}} <TodoList role="list" @todos={{this.todos}} as |Item index|> {{add index 1}}. <Item/> </TodoList> {{else}} No todos! {{/if}} Helpers Component attributes Component arguments Yielded variables
  13. WHY? ➤ Web Components ➤ Visually distinguish from control flow

    and values ➤ Ability to differentiate component vs passed in attributes
  14. DRAWBACKS ➤ Cannot use nested components ➤ Cannot use positional

    arguments ➤ Doesn’t work with {{link-to}}, {{input}} and {{textarea}} {{#link-to "about"}}About Us{{/link-to}} <LinkTo @route="about">About Us</LinkTo>
  15. NO CURLY COMPONENTS? ➤ Angle bracket components are recommended ➤

    Curly syntax will continue to work (at least as of now) ➤ Force by using template linting rules
  16. HISTORY ➤ Use to explicitly set an attribute ➤ Re-renders

    specific node that requires changes this.set export default Component.extend({ init() { setInterval(() => { this.set('date', new Date()); }, 1000); }, formattedTime: computed('date', function() { return moment(this.get('date')).format('h:mm:ss a'); }), message: computed('formattedTime', function() { return `It is currently ${this.get('formattedTime')}!`; }), }); <!-- This wrapper component gets ignored completely during rerenders --> <ClockWrapper theme="dark"> <!-- This text node is the _only_ thing that gets touched --> {{this.message}} </ClockWrapper>
  17. ANNOTATE IT export default class ClockComponent extends Component { @tracked

    date; constructor() { setInterval(() => (this.date = new Date()), 1000); }, get formattedTime() { return moment(this.date).format('h:mm:ss a'); } get message() { return `It is currently ${this.formattedTime}!`; } } If you change a class field and want the DOM to update, Make it tracked.
  18. WHY? ➤ Size reduction (1/5 reduction) ➤ Documentation, tests and

    core add-ons updated to not require by default
  19. HOW CAN I HELP? ➤ Contribute to guides ➤ Build

    Octane app using ember- octane-blueprint to playground with it and open issue(s)