Juan Antonio Gómez Benito
Technical Architect
BBVA Next Technologies
EmberJS Madrid Organizer
@shokmaster086
Framework para construir aplicaciones ambiciosas
Convention over configuration
Con solera
Empieza la fiebre de Angular. Se sospecha que Google está detrás.
Las apps con Backbone empiezan a irse de madre.
React es aún un embrión.
Corría el año 2013...
- Empezó como MVC
- Documentación infumable
- Convenciones de nombres poco claras
- Pocos desarrolladores del Core
- Muchos elementos distintos:
Route, Controller, View, Template, Model, Helper, Reopen, Mixin, Initializer, Router, Component...
- Lío en el router: resource/route
Los inicios fueron complicadillos...
Infierno en plantillas:
{{outlet}}
{{render "myTemplate"}}
{{view objectView}}
{{partial "myList"}}
Infierno en controladores:
ArrayController
ObjectController
ControllerMixin
- Nuevos paradigmas en front-end (CoC, generación implícita...)
- Mucha potencia con muy poco código
- Router robusto, rutas anidadas. De hecho es la base de Ember.
- Ember CLI (de nada, Angular )
- Glimmer VM en Ember v2.0
- Sensatez en las actualizaciones
...pero trajo muchas cosas ricas
Adrián González Rus
Software Crafter
BBVA Next Technologies
EmberJS Madrid Organizer
Native Classes
Angle Bracket
Elimination of jQuery
// Old style
import EmberObject, { computed } from '@ember/object';
export default EmberObject.extend({
firstName: 'Adrián',
lastName: 'González',
fullName: computed('firstName', 'lastName', function() {
return `${firstName} ${lastName}`;
})
});
// New style
import EmberObject, { computed } from '@ember/object';
export default class Person extends EmberObject {
firstName: 'Adrián',
lastName: 'González',
@computed('firstName', 'lastName')
get fullName() {
return `${firstName} ${lastName}`;
}
}
{{!-- Old Style --}}
{{site-header user=this.user class=(if this.user.isAdmin "admin")}}
{{#super-select selected=this.user.country as |option|}}
{{#each this.availableCountries as |country|}}
{{#s.option value=country}}{{country.name}}{{/s.option}}
{{/each}}
{{/super-select}}
<!-- New style -->
<SiteHeader @user={{this.user}} class={{if this.user.isAdmin "admin"}} />
<SuperSelect @selected={{this.user.country}} as |Option|>
{{#each this.availableCountries as |country|}}
<Option @value={{country}}>{{country.name}}</Option>
{{/each}}
</SuperSelect>
// Old style
import Component from '@ember/component';
export default Component.extend({
didRender() {
this._super(...arguments);
this.$('.button').click();
}
});
// New style
import Component from '@ember/component';
export default class MyComponent extends Component {
didRender() {
super(...arguments);
this.element.querySelector('.button').click();
}
}Release Management
Version Management
Deprecation Policy
Optional Features
Draft
Canary
Beta
Stable
LTS
Every 4 versions (aprox)
30 weeks of bug fixes
54 weeks of security patches
$ ember feature:list$ ember feature:enable some-feature$ ember feature:disable some-featureSergio del Valle Salvador
Software Engineer
BBVA IT Spain
EmberJS Madrid Organizer
@svsalvador
interface GlimmerComponent<T = object> {
args: T;
isDestroying: boolean;
isDestroyed: boolean;
constructor(owner: Opaque, args: T): void;
willDestroy(): void;
}Glimmer Components
Glimmer Components
// app/templates/simple-button.js
import Component from '@ember/component';
export default Component.extend({
tagName: 'button',
classNames: ['btn'],
attributeBindings: ['role'],
role: 'button',
});<!-- app/templates/components/simple-button.hbs -->
Haz click!<!-- app/templates/components/simple-button.hbs -->
<button class="btn" role="button">
Hello, world!
</button>Tracked properties
@tracked name;
get message() {
return `My name is ${this.name}!`;
}Tracked properties
export default class PersonalDataComponent extends Component {
@tracked firstName;
@tracked lastName;
get message() {
return `My name is ${this.firstName} ${this.lastName}`;
}
@action
updateName(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}