Ember Octane

Community

Tools

Ember usage

Ember Octane

Native Classes

Current Way

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);
  },
});

New Way (w/o Glimmer)

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);
  }
}

New Way (w/ Glimmer)

export default class PersonComponent extends Component {
  @tracked firstName;
  @tracked lastName;

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  @action
  updateName(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

Angle Bracket Invocation

{{#todo-list todos=todos as |item index|}}
    {{add index 1}}. {{item}}
{{/todo-list}}
<TodoList role="list" @todos={{todos}} as |Item index|>
    {{add index 1}}. <Item/>
</TodoList>

Tracked Properties

Current Way

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')}!`;
  }),
});

New Way

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}!`;
  }
}

Modifiers

<button {{action "handleClick"}}>
  Hello, World!
</button>
<button {{on "click" this.handleClick}}>
  Hello, World!
</button>

Glimmer

// 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!
<!-- app/templates/components/hello-button.hbs -->
<button class="btn" role="button">
  Hello, world!
</button>

Community

master / slaves        ->  primary / replica
whitelist / blacklist  ->  denylist / allowlist

github.com/davidhund/retext-assuming

github.com/yohanmishkin/ember-cli-alex

alexjs.com

Staying Up To Date and Getting Involved

Ember Community (Times, Observer, Discuss, Discord...)

Twitter (@tomdale, @wycats)

Tools

class Todo {
  id: number;
  @tracked title: string;
  @tracked completed: boolean;

  constructor(title: string, id: number, completed = false) {
    this.title = title;
    this.completed = completed;
    this.id = id;
  }

  toJSON(_key: string) {
    const { id, title, completed } = this;
    return { id, title, completed };
  }
}
type Args = {
  todos: Todo[];
};

class TodoList extends Component<Args> {
  @inject repo!: Repo;

  @tracked canToggle = true;

  get allCompleted(): boolean {
    return this.args.todos.isEvery("completed");
  }

  constructor(owner: Owner, args: Args) {
    super(owner, args);
    assert("`todos` is required", Array.isArray(args.todos));
  }
}

github.com/hjdivad/ember-m3

github.com/lytics/ember-data-model-fragments

github.com/orbitjs/ember-orbit

github.com/ember-a11y

w3.org/TR/WCAG21

Ember Usage

&

https://xiw.cx/ec-2019-notes

https://xiw.cx/ec-2019-slides