98
Suchita Doshi A paradigm shift A paradigm shift suchitadoshi suchitadoshi1987 suchita009 suchita009 1

When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Suchita Doshi

A paradigm shiftA paradigm shift

 suchitadoshi

 suchitadoshi1987

 suchita009

 suchita009

1

Page 2: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

When I am away from my computer...When I am away from my computer...

2

Page 3: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

When I am away from my computer...When I am away from my computer...

2

Page 4: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

When I am away from my computer...When I am away from my computer...

2

Page 5: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

When I am away from my computer...When I am away from my computer...

2

Page 6: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

When I am away from my computer...When I am away from my computer...

2

Page 7: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

AgendaAgenda

3

Page 8: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

AgendaAgenda

Journey Of EmberJSEmber 1.xEmber 2.xEmber 3.x

3

Page 9: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

AgendaAgenda

Journey Of EmberJS

Ember OctaneNative ClassesGlimmer ComponentsTemplates in OctaneTracked PropertiesModifiers & Decorators

3

Page 10: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

AgendaAgenda

Journey Of EmberJS

Ember Octane

Classic vs Octane Epiccomparison

3

Page 11: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

AgendaAgenda

Journey Of EmberJS

Ember Octane

Classic vs Octane Epiccomparison

Migration tools &References

3

Page 12: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

OfOf

TheThe

JOURNEYJOURNEY

4

Page 13: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 1.xEmber 1.x

5

Page 14: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Ember 1.xEmber 1.x

5

Page 15: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember 1.xEmber 1.x

5

Page 16: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember-data

Ember 1.xEmber 1.x

5

Page 17: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember-data

View Driven architecture

Ember 1.xEmber 1.x

5

Page 18: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember-data

View Driven architecture

Ember 1.xEmber 1.x

RouteController

+Templates

Model

View+

TemplatesModel

export default Ember.View.extend({

// Computed Property fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName'), fullNameChanged: function() { // deal with the change }.observes('fullName')});

1 classNameBindings: ['isActive'],2 isActive: true,3 firstName: 'John',4 lastName: 'Doe',5 6

789101112131415

5

Page 19: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember-data

View Driven architecture

Two way data bindings

Ember 1.xEmber 1.x

5

Page 20: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Convention over configuration (A new mental model)

Built-in Routing capability

Ember-data

View Driven architecture

Two way data bindings

Attribute bindings using {{bind-attr}}

Ember 1.xEmber 1.x

<div {{bind-attr title=post.popup}}></div>1

5

Page 21: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 2.xEmber 2.x

6

Page 22: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

Ember 2.xEmber 2.x

export default Ember.Component.extend({

// Computed Property fullName: Ember.computed('firstName', 'lastName', function() { return this.get('firstName') + ' ' + this.get('lastName'); }), fullNameChanged: Ember.observer('fullName', function() { // deal with the change })});

1 classNameBindings: ['isActive'],2 isActive: true,3 firstName: 'John',4 lastName: 'Doe',5 6

789

101112131415

RouteController

+Templates

Component+

TemplatesModelModel

6

Page 23: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Ember 2.xEmber 2.x

6

Page 24: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Better binding with properties {{bind-attr}}

Ember 2.xEmber 2.x

// v2.x

<div title="{{post.popup}}"></div>1

<div {{bind-attr title=post.popup}}></div>1

// v1.x

6

Page 25: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Better binding with properties {{bind-attr}}

Better template scoping

Ember 2.xEmber 2.x

6

Page 26: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Better binding with properties {{bind-attr}}

Better template scoping

Ember 2.xEmber 2.x

6

// v1.x

{{!-- 1.x version --}}{{#each post in posts}} {{!-- `post` references the current iteration --}}{{/each}} {{#each posts}} {{!-- the outer context is no longer accessible --}}{{/each}}

123456789

1011

// v2.x

{{!-- 2.x version --}} {{#each posts as |post|}} {{!--`post` references the current iteration --}} <p>{{post.id}} {{post.title}}</p>{{/each}}

1234567

Page 27: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Better binding with properties {{bind-attr}}

Better template scoping

"Data Down, Actions Up" approach

Ember 2.xEmber 2.x

6

Page 28: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Component driven

“Glimmer rendering engine” adoption

Better binding with properties {{bind-attr}}

Better template scoping

"Data Down, Actions Up" approach

Roadmap for a lot of further improvements:

HTML syntax for component invocation

Routes to drive Components approach

Ember 2.xEmber 2.x

6

Page 29: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

7

Page 30: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

7

Page 31: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

7

Page 32: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

7

Page 33: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

7

Page 34: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

Glimmer Components

7

Page 35: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

Glimmer Components

Angle Brackets Invocation

7

Page 36: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

Glimmer Components

Angle Brackets Invocation

@tracked properties

7

Page 37: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

Glimmer Components

Angle Brackets Invocation

@tracked properties

Modifiers & Decorators

7

Page 38: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)

Cleanup Cleanup Cleanup

Remove support for IE9, IE10 and PhantomJS.

Remove bower support

Native Classes

Glimmer Components

Angle Brackets Invocation

@tracked properties

Modifiers & Decorators

Lots of documentation 7

Page 39: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Evolution of EmberJSEvolution of EmberJS

8

Page 40: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Evolution of EmberJSEvolution of EmberJS

1.x

8

Page 41: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Evolution of EmberJSEvolution of EmberJS

2.x1.x

8

Page 42: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Evolution of EmberJSEvolution of EmberJS

2.x1.x 3.x

8

Page 43: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Evolution of EmberJSEvolution of EmberJS

Octane2.x1.x 3.x

8

Page 44: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

9

Page 45: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

10

Page 46: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

10

Page 47: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

10

Page 48: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

10

Page 49: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

10

Page 50: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

10

Page 51: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

10

Page 52: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

Cleaner and easier to read

10

Page 53: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

Cleaner and easier to read

import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');

12345678910111213141516

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });

1234567891011121314

// Classic Ember Object Syntax

// Native Class Syntax

10

Page 54: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

Cleaner and easier to read

import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');

12345678910111213141516

class Person {

}

import { computed } from '@ember/object'1 2

3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13

14 15let phoenix = new Person('Jean', 'Gray');16

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });

1234567891011121314

const Person = EmberObject.extend({

});

import EmberObject, { computed } from '@ember/object';1 2

3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11

12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14

// Classic Ember Object Syntax

// Native Class Syntax

10

Page 55: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

Cleaner and easier to read

import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');

12345678910111213141516

class Person {

}

import { computed } from '@ember/object'1 2

3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13

14 15let phoenix = new Person('Jean', 'Gray');16

@computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }

import { computed } from '@ember/object'1 2class Person {3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9

10111213

}14 15let phoenix = new Person('Jean', 'Gray');16

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });

1234567891011121314

const Person = EmberObject.extend({

});

import EmberObject, { computed } from '@ember/object';1 2

3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11

12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14

fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8

91011

});12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14

// Classic Ember Object Syntax

// Native Class Syntax

10

Page 56: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Native ClassesNative Classes

ES6 Class syntax

Increased performance

Smooth learning curve

More aligned Javascript

community

Ability to share code more

easily

No more `.get`'s

Cleaner and easier to read

import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');

12345678910111213141516

class Person {

}

import { computed } from '@ember/object'1 2

3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13

14 15let phoenix = new Person('Jean', 'Gray');16

@computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }

import { computed } from '@ember/object'1 2class Person {3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9

10111213

}14 15let phoenix = new Person('Jean', 'Gray');16

import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');

12345678910111213141516

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });

1234567891011121314

const Person = EmberObject.extend({

});

import EmberObject, { computed } from '@ember/object';1 2

3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11

12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14

fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8

91011

});12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });

1234567891011121314

// Classic Ember Object Syntax

// Native Class Syntax

10

Page 57: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Glimmer ComponentsGlimmer Components

11

Page 58: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

// Classic Component

// Glimmer Component

11

Page 59: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

// Classic Component

// Glimmer Component

11

Page 60: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and propertiesimport Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

// Classic Component

// Glimmer Component

11

Page 61: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and properties

No more implicit wrappers

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

// Classic Component

// Glimmer Component

11

Page 62: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and properties

No more implicit wrappers

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

{{noOfGuests}}1

// Classic Component

// Glimmer Component

11

Page 63: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and properties

No more implicit wrappers

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

{{noOfGuests}}1

<label> {{this.noOfGuests}} </label>1

// Classic Component

// Glimmer Component

11

Page 64: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and properties

No more implicit wrappers

Namespaced arguments

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

return this.noOfGuests > this.args.maxGuests;

import Component from "@glimmer/component";1import { tracked } from "@glimmer/tracking";2 3export default class AddRsvp extends Component {4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8

9 }10 11}12

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

return this.noOfGuests > this.maxGuests;

import Component from '@ember/component';1 2export default Component.extend({3 4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9

10 }11});12

{{noOfGuests}}1

<label> {{this.noOfGuests}} </label>1

// Classic Component

// Glimmer Component

11

Page 65: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Offers simpler, ergonomic,

and declarative approach

Easier to understand

Fewer hooks and properties

No more implicit wrappers

Namespaced arguments

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";

export default class AddRsvp extends Component {

1import { tracked } from "@glimmer/tracking";2 3

4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

return this.noOfGuests > this.args.maxGuests;

import Component from "@glimmer/component";1import { tracked } from "@glimmer/tracking";2 3export default class AddRsvp extends Component {4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8

9 }10 11}12

import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }

123456789

101112

Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

import Component from '@ember/component'; export default Component.extend({

123

4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

tagName: 'label',

import Component from '@ember/component';1 2export default Component.extend({3 4

5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12

return this.noOfGuests > this.maxGuests;

import Component from '@ember/component';1 2export default Component.extend({3 4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9

10 }11});12

import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});

123456789

101112

{{noOfGuests}}1

<label> {{this.noOfGuests}} </label>1

// Classic Component

// Glimmer Component

11

Page 66: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Templating in OctaneTemplating in Octane

12

Page 67: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Templating in OctaneTemplating in Octane

Angle Brackets syntax

In line with the HTML standards

Capital Case Syntax

Easy to distinguish from helpers,properties etc.

{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}

123456

{{employee-details

}}

1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4

56

<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>

12345

<EmployeeDetails

/>

1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4

5

// Classic templating syntax

// Octane templating syntax

12

Page 68: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Templating in OctaneTemplating in Octane

Angle Brackets syntax

In line with the HTML standards

Capital Case Syntax

Easy to distinguish from helpers,properties etc.

Named arguments

Denoted with `@` symbol

Easy differentiation from local andexternal properties

{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}

123456

{{employee-details

}}

1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4

56

name=employeeName empId=employeeId addEmployee=(action 'addEmployee')

{{employee-details1234

}}56

<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>

12345

<EmployeeDetails

/>

1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4

5

@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}

<EmployeeDetails1234

/>5

// Classic templating syntax

// Octane templating syntax

12

Page 69: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Templating in OctaneTemplating in Octane

Angle Brackets syntax

In line with the HTML standards

Capital Case Syntax

Easy to distinguish from helpers,properties etc.

Named arguments

Denoted with `@` symbol

Easy differentiation from local andexternal properties

Required `this`

Provides clear point-of-origin

Easy to read and understand

{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}

123456

{{employee-details

}}

1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4

56

name=employeeName empId=employeeId addEmployee=(action 'addEmployee')

{{employee-details1234

}}56

name=employeeName{{employee-details1

2 empId=employeeId3 addEmployee=(action 'addEmployee')4}}5

6

<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>

12345

<EmployeeDetails

/>

1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4

5

@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}

<EmployeeDetails1234

/>5

@name={{this.employeeName}}<EmployeeDetails1

2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4/>5

// Classic templating syntax

// Octane templating syntax

12

Page 70: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Templating in OctaneTemplating in Octane

Angle Brackets syntax

In line with the HTML standards

Capital Case Syntax

Easy to distinguish from helpers,properties etc.

Named arguments

Denoted with `@` symbol

Easy differentiation from local andexternal properties

Required `this`

Provides clear point-of-origin

Easy to read and understand

{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}

123456

{{employee-details

}}

1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4

56

name=employeeName empId=employeeId addEmployee=(action 'addEmployee')

{{employee-details1234

}}56

name=employeeName{{employee-details1

2 empId=employeeId3 addEmployee=(action 'addEmployee')4}}5

6

{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}

123456

<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>

12345

<EmployeeDetails

/>

1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4

5

@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}

<EmployeeDetails1234

/>5

@name={{this.employeeName}}<EmployeeDetails1

2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4/>5

<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>

12345

// Classic templating syntax

// Octane templating syntax

12

Page 71: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

// Classic syntax

// @tracked syntax

13

Page 72: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

// Classic syntax

// @tracked syntax

13

Page 73: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

firstName: 'Tom', lastName: 'Dale', count: 0,

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3

456

7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;

import { tracked } from '@glimmer/tracking';1 2class Person {3

456

7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

// Classic syntax

// @tracked syntax

13

Page 74: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

firstName: 'Tom', lastName: 'Dale', count: 0,

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3

456

7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

fullName: computed('firstName', 'lastName', function() {

}),

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7

8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10

11});12

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;

import { tracked } from '@glimmer/tracking';1 2class Person {3

456

7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

get fullName() {

}

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7

8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10

11}12

// Classic syntax

// @tracked syntax

13

Page 75: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

firstName: 'Tom', lastName: 'Dale', count: 0,

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3

456

7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

fullName: computed('firstName', 'lastName', function() {

}),

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7

8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10

11});12

this.set('count', this.get('count') + 1);

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8

9 return `${this.firstName} ${this.lastName}`;10 }),11});12

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;

import { tracked } from '@glimmer/tracking';1 2class Person {3

456

7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

get fullName() {

}

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7

8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10

11}12

this.count = this.count + 1;

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8

9 return `${this.firstName} ${this.lastName}`;10 }11}12

// Classic syntax

// @tracked syntax

13

Page 76: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tracked PropertiesTracked Properties

@tracked syntax

Explicit declarations

Cleaner code

Reduces complexity

No More `.set`'s

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

firstName: 'Tom', lastName: 'Dale', count: 0,

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3

456

7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12

fullName: computed('firstName', 'lastName', function() {

}),

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7

8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10

11});12

this.set('count', this.get('count') + 1);

import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8

9 return `${this.firstName} ${this.lastName}`;10 }),11});12

import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});

123456789101112

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;

import { tracked } from '@glimmer/tracking';1 2class Person {3

456

7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12

get fullName() {

}

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7

8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10

11}12

this.count = this.count + 1;

import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8

9 return `${this.firstName} ${this.lastName}`;10 }11}12

import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}

123456789101112

// Classic syntax

// @tracked syntax

13

Page 77: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Modifiers and DecoratorsModifiers and Decorators

14

Page 78: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Modifiers and DecoratorsModifiers and Decorators

Modifiers:

Functions or classes useddirectly in templates

Applied directly to elements

Allows targeting specificelements more easily

Easy to reuse

<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

123456

<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

<span>{{this.formattedCount}}</span>1 2

3456

14

Page 79: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Modifiers and DecoratorsModifiers and Decorators

Modifiers:

Functions or classes useddirectly in templates

Applied directly to elements

Allows targeting specificelements more easily

Easy to reuse

Decorators:

Abstracts functionality

Improved Developer experience

<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

123456

<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

<span>{{this.formattedCount}}</span>1 2

3456

<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

123456

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}

123456789

101112131415161718192021

@action

@action

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class Counter extends Component {5 @tracked count = 0;6 7 get formattedCount() {8 return this.count.toString().padStart(3, '0');9 }10 11

12 increment() {13 this.count++14 }15 16

17 decrement() {18 this.count--19 }20}21

14

Page 80: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Modifiers and DecoratorsModifiers and Decorators

Modifiers:

Functions or classes useddirectly in templates

Applied directly to elements

Allows targeting specificelements more easily

Easy to reuse

Decorators:

Abstracts functionality

Improved Developer experience

<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

123456

<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

<span>{{this.formattedCount}}</span>1 2

3456

<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>

123456

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}

123456789

101112131415161718192021

@action

@action

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class Counter extends Component {5 @tracked count = 0;6 7 get formattedCount() {8 return this.count.toString().padStart(3, '0');9 }10 11

12 increment() {13 this.count++14 }15 16

17 decrement() {18 this.count--19 }20}21

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}

123456789

101112131415161718192021

14

Page 81: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

15

Page 82: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

// Classic Component syntax

15

Page 83: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

// Classic Component syntax

15

Page 84: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

// Classic Component syntax

15

Page 85: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 86: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 87: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 88: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 89: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 90: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8

910111213

isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}

<label123456789

"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 91: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8

910111213

isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13

141516171819

20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

@tracked isAwesome = true;

get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5

6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11

12131415

16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}

<label123456789

"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 92: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8

910111213

isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13

141516171819

20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20

2122232425

26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

@tracked isAwesome = true;

get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5

6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11

12131415

16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

get type() { return this.args.value ? 'on' : 'off'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7

89

10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}

<label123456789

"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 93: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8

910111213

isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13

141516171819

20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20

2122232425

26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26

2728293031

});32

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

@tracked isAwesome = true;

get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5

6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11

12131415

16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

get type() { return this.args.value ? 'on' : 'off'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7

89

10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

@action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16

171819202122

}23 24

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}

<label123456789

"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{on 'click' this.handleClick}}

<label1 for="{{@switchId}}"2

3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 94: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1

2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

export default Component.extend({

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5

6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

tagName: 'label',

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7

8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8

910111213

isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13

141516171819

20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20

2122232425

26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32

click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }

import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26

2728293031

});32

import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});

123456789

1011121314151617181920212223242526272829303132

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5

6

{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}

123456

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

export default class ToggleLabel extends Component {

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4

5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23

24

@tracked isAwesome = true;

get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5

6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11

12131415

16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

get type() { return this.args.value ? 'on' : 'off'; }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7

89

10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24

@action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }

import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16

171819202122

}23 24

import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}

123456789

101112131415161718192021222324

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label

</label>

1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16

1718

for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}

<label123456789

"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

{{on 'click' this.handleClick}}

<label1 for="{{@switchId}}"2

3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17

18

<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>

123456789

101112131415161718

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>

12345

// Classic Component syntax // Octane Component syntax

15

Page 95: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tools & GoodnessTools & Goodness

16

Page 96: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tools & GoodnessTools & Goodness

Ember Codemods: https://github.com/ember-codemods

Ember Atlas: https://www.notion.so/The-Ember-Atlas-

4094f81c86c34badb4a562ed29414ae1

The Octane Edition of Ember: 

https://emberjs.com/editions/octane/

Ember Blog - Octane is Here:

https://blog.emberjs.com/2019/12/20/octane-is-here.html

16

Page 97: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Tools & GoodnessTools & Goodness

Ember Codemods: https://github.com/ember-codemods

Ember Atlas: https://www.notion.so/The-Ember-Atlas-

4094f81c86c34badb4a562ed29414ae1

The Octane Edition of Ember: 

https://emberjs.com/editions/octane/

Ember Blog - Octane is Here:

https://blog.emberjs.com/2019/12/20/octane-is-here.html

 16

Page 98: When I am a way from my computer · 2020. 3. 18. · S u chi t a D o s h i A pa ra digm s h i f t suchitadoshi suchitadoshi1987 suchita009 suchita009 1. When I am a way from my computer

Thank you!Thank you!

17