5. Ember.js
Da creatori/sviluppatori di jQuery, Rails, SproutCore
Moderno framework JS (v.1.0-beta - agosto 2012)
“The web derives its power from the
ability to bookmark and share URLs”
6. Ember.js
Da creatori/sviluppatori di jQuery, Rails, SproutCore
Moderno framework JS (v.1.0-beta - agosto 2012)
Finora piuttosto instabile, ma v.2.0 il 24/07/15
“The web derives its power from the
ability to bookmark and share URLs”
7. Ember.js
Da creatori/sviluppatori di jQuery, Rails, SproutCore
Moderno framework JS (v.1.0-beta - agosto 2012)
Finora piuttosto instabile, ma v.2.0 il 24/07/15
Opinionated framework: convention-over-configuration
“The web derives its power from the
ability to bookmark and share URLs”
8. Ember.js
Da creatori/sviluppatori di jQuery, Rails, SproutCore
Moderno framework JS (v.1.0-beta - agosto 2012)
Finora piuttosto instabile, ma v.2.0 il 24/07/15
Opinionated framework: convention-over-configuration
Largo uso di ECMAScript 6 (o simili, come RSVP)
“The web derives its power from the
ability to bookmark and share URLs”
13. Ember-cli
Command-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars,
CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
Rigida struttura convenzionale di file/cartelle (occhio ai nomi!)
14. Ember-cli
Command-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars,
CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
Rigida struttura convenzionale di file/cartelle (occhio ai nomi!)
Compilazione al volo ad ogni file salvato in sviluppo
15. Ember-cli
Command-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars,
CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
Rigida struttura convenzionale di file/cartelle (occhio ai nomi!)
Compilazione al volo ad ogni file salvato in sviluppo
Generatori di risorse, server di sviluppo, installazione addon
16. Ember-cli
Command-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars,
CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
Rigida struttura convenzionale di file/cartelle (occhio ai nomi!)
Compilazione al volo ad ogni file salvato in sviluppo
Generatori di risorse, server di sviluppo, installazione addon
Test con PhantomJS
17. Ember-cli - up & running
npm install -g ember-cli bower phantomjs
ember new my-new-app
cd my-new-app
npm install && bower install
ember server
30. Ember-cli - generatori
ember generate <generator-name> <options>
Con l’opzione --pod si possono mantenere tutti i file
relativi ad una risorsa nella stessa cartella:
• app/users/controller.js
• app/users/route.js
• app/users/template.hbs
32. Ember-cli - generatori
Available blueprints:
liquid-fire:
transition <name>
Generates a liquid fire transition.
ember-select-2:
ember-select-2 <name>
ember-moment:
ember-moment <name>
ember-addon:
ember-data <name>
ember-cli-simple-auth-devise:
ember-cli-simple-auth-devise <name>
ember-cli-simple-auth:
authenticator <name>
Generates an Ember Simple Auth authenticator.
authorizer <name>
Generates an Ember Simple Auth Authorizer.
ember-cli-simple-auth <name>
session <name>
Generates an Ember Simple Auth Session.
session-store <name>
Generates an Ember Simple Auth Session Store.
ember-cli-qunit:
ember-cli-qunit <name>
ember-cli-divshot:
divshot <name>
ember-cli-bootstrap-datepicker:
bootstrap-datepicker <name>
ember-cli:
acceptance-test <name>
Generates an acceptance test for a feature.
adapter <name> <options...>
Generates an ember-data adapter.
--base-class
adapter-test <name>
Generates an ember-data adapter unit test
addon <name>
The default blueprint for ember-cli addons.
addon-import <name>
Generates an import wrapper.
app <name>
The default blueprint for ember-cli projects.
blueprint <name>
Generates a blueprint and definition.
component <name> <options...>
Generates a component. Name must contain a hyphen.
--path (Default: components)
aliases: -no-path (--path=)
component-addon <name>
Generates a component. Name must contain a hyphen.
component-test <name>
Generates a component unit test.
controller <name>
Generates a controller.
controller-test <name>
Generates a controller unit test.
helper <name>
Generates a helper function.
helper-addon <name>
Generates an import wrapper.
helper-test <name>
Generates a helper unit test.
http-mock <endpoint-path>
Generates a mock api endpoint in /api prefix.
http-proxy <local-path> <remote-url>
Generates a relative proxy to another server.
in-repo-addon <name>
The blueprint for addon in repo ember-cli addons.
initializer <name>
Generates an initializer.
initializer-addon <name>
Generates an import wrapper.
initializer-test <name>
Generates an initializer unit test.
lib <name>
Generates a lib directory for in-repo addons.
mixin <name>
Generates a mixin.
mixin-test <name>
Generates a mixin unit test.
model <name> <attr:type>
Generates an ember-data model.
model-test <name>
Generates a model unit test.
resource <name>
Generates a model and route.
route <name> <options...>
Generates a route and registers it with the router.
--path (Default: )
route-addon <name>
Generates import wrappers for a route and its template.
route-test <name>
Generates a route unit test.
serializer <name>
Generates an ember-data serializer.
serializer-test <name>
Generates a serializer unit test.
server <name>
Generates a server directory for mocks and proxies.
service <name>
Generates a service.
service-test <name>
Generates a service unit test.
template <name>
Generates a template.
test-helper <name>
Generates a test helper.
transform <name>
Generates an ember-data value transform.
transform-test <name>
Generates a transform unit test.
util <name>
Generates a simple utility module/function.
util-test <name>
Generates a util unit test.
view <name>
Generates a view subclass.
view-test <name>
ember help generate
33. Ember-cli - generatori
Available blueprints:
liquid-fire:
transition <name>
Generates a liquid fire transition.
ember-select-2:
ember-select-2 <name>
ember-moment:
ember-moment <name>
ember-addon:
ember-data <name>
ember-cli-simple-auth-devise:
ember-cli-simple-auth-devise <name>
ember-cli-simple-auth:
authenticator <name>
Generates an Ember Simple Auth authenticator.
authorizer <name>
Generates an Ember Simple Auth Authorizer.
ember-cli-simple-auth <name>
session <name>
Generates an Ember Simple Auth Session.
session-store <name>
Generates an Ember Simple Auth Session Store.
ember-cli-qunit:
ember-cli-qunit <name>
ember-cli-divshot:
divshot <name>
ember-cli-bootstrap-datepicker:
bootstrap-datepicker <name>
ember-cli:
acceptance-test <name>
Generates an acceptance test for a feature.
adapter <name> <options...>
Generates an ember-data adapter.
--base-class
adapter-test <name>
Generates an ember-data adapter unit test
addon <name>
The default blueprint for ember-cli addons.
addon-import <name>
Generates an import wrapper.
app <name>
The default blueprint for ember-cli projects.
blueprint <name>
Generates a blueprint and definition.
component <name> <options...>
Generates a component. Name must contain a hyphen.
--path (Default: components)
aliases: -no-path (--path=)
component-addon <name>
Generates a component. Name must contain a hyphen.
component-test <name>
Generates a component unit test.
controller <name>
Generates a controller.
controller-test <name>
Generates a controller unit test.
helper <name>
Generates a helper function.
helper-addon <name>
Generates an import wrapper.
helper-test <name>
Generates a helper unit test.
http-mock <endpoint-path>
Generates a mock api endpoint in /api prefix.
http-proxy <local-path> <remote-url>
Generates a relative proxy to another server.
in-repo-addon <name>
The blueprint for addon in repo ember-cli addons.
initializer <name>
Generates an initializer.
initializer-addon <name>
Generates an import wrapper.
initializer-test <name>
Generates an initializer unit test.
lib <name>
Generates a lib directory for in-repo addons.
mixin <name>
Generates a mixin.
mixin-test <name>
Generates a mixin unit test.
model <name> <attr:type>
Generates an ember-data model.
model-test <name>
Generates a model unit test.
resource <name>
Generates a model and route.
route <name> <options...>
Generates a route and registers it with the router.
--path (Default: )
route-addon <name>
Generates import wrappers for a route and its template.
route-test <name>
Generates a route unit test.
serializer <name>
Generates an ember-data serializer.
serializer-test <name>
Generates a serializer unit test.
server <name>
Generates a server directory for mocks and proxies.
service <name>
Generates a service.
service-test <name>
Generates a service unit test.
template <name>
Generates a template.
test-helper <name>
Generates a test helper.
transform <name>
Generates an ember-data value transform.
transform-test <name>
Generates a transform unit test.
util <name>
Generates a simple utility module/function.
util-test <name>
Generates a util unit test.
view <name>
Generates a view subclass.
view-test <name>
Anche gli addon possono aggiungere generatori
ember help generate
40. application.hbs
1 <h2 id="title">Welcome to Ember.js</h2>
2
3 {{outlet}}
{{outlet}}
definisce dove i
template “figli” devono
inserire il loro
contenuto
Tutti i template derivano da application.hbs
41. Template - HTMLBars
1 {{#if users}}
2 {{#each users as |user|}}
3 <p class="user {{if user.isActive 'active' 'inactive'}}">
4 User: {{#link-to 'users.profile' user}}{{user.name}}{{/link-to}}
5 <button {{action "like" user}}>Like</button>
6 </p>
7 {{/each}}
8 {{else}}
9 Nobody's here..
10 {{/if}}
È una variante di HandleBars che genera DOM
invece di stringhe, con notevole incremento di
prestazioni (+30%)
42. Routing
1 import Ember from 'ember';
2 import config from './config/environment';
3
4 var Router = Ember.Router.extend({
5 location: config.locationType
6 });
7
8 Router.map(function() {
9 this.route('people', function() {
10 this.route('new');
11 this.route('edit', {path: '/:id/edit'});
12 this.route('contracts', { path: '/:person_id/contracts' });
13 });
14 });
Ember.js si fonda sull’URL
Il file router.js definisce le rotte e la mappatura degli url:
43. Routing
1 Router.map(function() {
2 this.route('people', function() {});
3 });
error e loading sono due rotte usate automaticamente quando il modello è
in fase di caricamento o è in errore
44. Routing
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4
5 model: function(params) {
6 return this.store.find('myModel', params);
7 },
8
9 setupController: function(controller, model) {
10 controller.set('model', model);
11 }
12 });
Implementazione di base di una rotta:
Quindi nel controller e nel template è disponibile il
modello
46. Modello associato
Ogni rotta ha un modello associato
Il modello può essere un POJO, il risultato di una
chiamata AJAX con jQuery oppure ottenuto con
Ember-data e lo store
47. Modello associato
Ogni rotta ha un modello associato
Il modello può essere un POJO, il risultato di una
chiamata AJAX con jQuery oppure ottenuto con
Ember-data e lo store
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4
5 model: function() {
6 return this.store.find('myModel');
7 }
8 });
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4
5 model: function() {
6 return Ember.$.getJSON(/*…*/)
7 }
8 });
48. Store
Lo store astrae il backend
Il modello vive sul client e si sincronizza col backend
var model = this.store.find('user', 1);
model.deleteRecord();
// il modello non è più sullo store
// ma va sincronizzato col backend
model.save().catch(function() {
// ops! Torniamo indietro
model.rollback();
});
49. Store
Lo store astrae il backend
Il modello vive sul client e si sincronizza col backend
var model = this.store.find('user', 1);
model.deleteRecord();
// il modello non è più sullo store
// ma va sincronizzato col backend
model.save().catch(function() {
// ops! Torniamo indietro
model.rollback();
});
La configurazione dello store (con gli adapters e serializzatori)
permette di lavorare con ogni backend (anche legacy!)
51. Modelli
8 roles: DS.hasMany('roles', { embedded: 'always' }),
9 office: DS.belongsTo('office', { async: true }),
I modelli possono essere in relazione tra loro:
52. Modelli
8 roles: DS.hasMany('roles', { embedded: 'always' }),
9 office: DS.belongsTo('office', { async: true }),
I modelli possono essere in relazione tra loro:
Nel primo caso i dati sono forniti dal backend
insieme al modello
53. Modelli
8 roles: DS.hasMany('roles', { embedded: 'always' }),
9 office: DS.belongsTo('office', { async: true }),
I modelli possono essere in relazione tra loro:
Nel primo caso i dati sono forniti dal backend
insieme al modello
Nel secondo caso il modello contiene l’ID del
modello associato e viene caricato in maniera
asincrona quando necessario con una chiamata
specifica
54. Modelli
15 rolesList: function() {
16 return this.get('roles').map(function(role){
17 return role.get('name');
18 });
19 }.property('roles.@each')
Le proprietà elaborate (computed properties)
sono attributi bidirezionali non direttamente
ottenuti attraverso il backend ma calcolati
usando altri attributi (anche altre computed
properties)
56. Controller
1 {{#if showForm}}
2 <form>
3 ...
4 </form>
5 <button {{action 'toggleFormVisibility'}}>Nascondi il form</button>
6 {{else}}
7 <button {{action 'toggleFormVisibility'}}>Mostra il form</button>
8 {{/if}}
I controller “preparano” il modello e altri dati per l’uso nei template
57. Controller
1 {{#if showForm}}
2 <form>
3 ...
4 </form>
5 <button {{action 'toggleFormVisibility'}}>Nascondi il form</button>
6 {{else}}
7 <button {{action 'toggleFormVisibility'}}>Mostra il form</button>
8 {{/if}}
1 import Ember from 'ember';
2
3 export default Ember.Controller.extend({
4 showForm: false,
5
6 actions: {
7 toggleFormVisibility: function() {
8 this.set('showForm', !this.get('showForm'));
9 }
10 }
11 });
I controller “preparano” il modello e altri dati per l’uso nei template
59. Controller
1 import Ember from 'ember';
2
3 export default Ember.Controller.extend({
4 showForm: false,
5
6 formVisibilityObserver: function() {
7 console.log('Il form è visibile');
8 }.observes('showForm'),
9
10 modelNameObserver: function() {
11 console.log('Il nome del modello è cambiato');
12 }.observes('model.name')
13 });
Gli observer possono rimanere in “ascolto” di
cambiamenti negli attributi
60. Action bubbling
1 <button {{action "like" user}}>Like</button>
Le azioni risalgono fino a trovare l’implementazione
nel controller o nella rotta, fino alla rotta globale
(ApplicationRoute), ad esempio:
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4 actions: {
5 like: function(user) {
6 // Implementazione
7 }
8 }
9 });
61. Azioni: rotta o controller?
Le azioni possono essere definite sia nella rotta che
nel controller. Qual’è il posto giusto?
La convenzione è che la rotta ospiti azioni che hanno un
impatto diretto sul modello, mentre il controller
gestisca le azioni che hanno impatto sui template e
sul flusso di controllo
64. Componenti
• Formate da un file js di logica e gestione azioni e
un template
• Forniscono componenti riusabili nel codice con
una propria logica funzionale anche complessa
65. Componenti
• Formate da un file js di logica e gestione azioni e
un template
• Forniscono componenti riusabili nel codice con
una propria logica funzionale anche complessa
• Esistono anche gli helper che hanno un uso più
banale (ad esempio formattare le date)
66. Componenti
Le componenti sostituiscono le viste delle vecchie versioni di Ember
• Formate da un file js di logica e gestione azioni e
un template
• Forniscono componenti riusabili nel codice con
una propria logica funzionale anche complessa
• Esistono anche gli helper che hanno un uso più
banale (ad esempio formattare le date)