SlideShare ist ein Scribd-Unternehmen logo
1 von 72
Downloaden Sie, um offline zu lesen
Testo
Introduzione a Ember.js
“A framework for creating ambitious web applications”
Agenda
Ember e ember-cli
Template
Routing
Modelli e Ember-Data
Controller
Componenti
Addons
Risorse
Ember.js
“The web derives its power from the
ability to bookmark and share URLs”
Ember.js
Da creatori/sviluppatori di jQuery, Rails, SproutCore
“The web derives its power from the
ability to bookmark and share URLs”
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”
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”
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”
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”
Ciclo di sviluppo
Release Beta Canary
1.13.0 2.0.0-beta1 2.0.0-canary+680f997e
Ember-cli
Ember-cli
Command-line-interface per gestire un progetto Ember
Ember-cli
Command-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars,
CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
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!)
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
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
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
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
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Configurazioni
dell’applicazione
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Gestione delle
dipendenze del
frontend (bower)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Gestione delle
dipendenze del
backend (Node.js)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Specifiche della
compilazione di
Broccoli (librerie,
pacchetti, ecc.)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Ember 1.x: MVC
Model: gestione dati (prob. ember-data)
View (templates): presentazione dati
(handlebars)
Controller: manipolazione dati per il
template
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Ember 2.x: full-stack web
framework
Model: gestione dati (prob. ember-data)
Components: componenti riusabili
Templates: presentazione dati (HTMLbars)
Router: recupero dati, gestione delle azioni
dei template, salvataggio, redirect, ecc.
(store, ember-data)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Specifiche delle rotte
definisce gli URL (in Ember gli URL
devono essere consistenti)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Componenti
elementi riusabili
nell’applicazione, composti da
logica+template
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Adapters
logica di gestione delle API (come
passare i dati, dove ottenerli,
ecc.)
Ember-cli - struttura file
app/
— adapters/
— components/
— controllers/
— helpers/
— models/
— routes/
— styles/
— templates/
— app.js
— index.html
— router.js
config/environment.js
bower.json
ember-cli-build.js
package.json
Helpers
funzioni riusabili (es. parsing di
date con Moment.js)
Ember-cli - generatori
ember generate <generator-name> <options>
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
Ember-cli - generatori
ember help generate
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
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
index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title>MyNewApp</title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 {{content-for 'head'}}
11
12 <link rel="stylesheet" href="assets/vendor.css">
13 <link rel="stylesheet" href="assets/my-new-app.css">
14
15 {{content-for 'head-footer'}}
16 </head>
17 <body>
18 {{content-for 'body'}}
19
20 <script src="assets/vendor.js"></script>
21 <script src="assets/my-new-app.js"></script>
22
23 {{content-for 'body-footer'}}
24 </body>
25 </html>
index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title>MyNewApp</title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 {{content-for 'head'}}
11
12 <link rel="stylesheet" href="assets/vendor.css">
13 <link rel="stylesheet" href="assets/my-new-app.css">
14
15 {{content-for 'head-footer'}}
16 </head>
17 <body>
18 {{content-for 'body'}}
19
20 <script src="assets/vendor.js"></script>
21 <script src="assets/my-new-app.js"></script>
22
23 {{content-for 'body-footer'}}
24 </body>
25 </html>
vendor.css e
vendor.js contengono
css e js delle librerie
esterne
index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title>MyNewApp</title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 {{content-for 'head'}}
11
12 <link rel="stylesheet" href="assets/vendor.css">
13 <link rel="stylesheet" href="assets/my-new-app.css">
14
15 {{content-for 'head-footer'}}
16 </head>
17 <body>
18 {{content-for 'body'}}
19
20 <script src="assets/vendor.js"></script>
21 <script src="assets/my-new-app.js"></script>
22
23 {{content-for 'body-footer'}}
24 </body>
25 </html>
index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title>MyNewApp</title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 {{content-for 'head'}}
11
12 <link rel="stylesheet" href="assets/vendor.css">
13 <link rel="stylesheet" href="assets/my-new-app.css">
14
15 {{content-for 'head-footer'}}
16 </head>
17 <body>
18 {{content-for 'body'}}
19
20 <script src="assets/vendor.js"></script>
21 <script src="assets/my-new-app.js"></script>
22
23 {{content-for 'body-footer'}}
24 </body>
25 </html>
my-new-app.css
e my-new-app.js
contengono css e js
dell’app
application.hbs
1 <h2 id="title">Welcome to Ember.js</h2>
2
3 {{outlet}}
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
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
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%)
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:
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
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
Modello associato
Ogni rotta ha un modello associato
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
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 });
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();
});
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!)
Definire un modello
1 import DS from 'ember-data';
2
3 export default DS.Model.extend({
4 name: DS.attr('string'),
5 surname: DS.attr('string'),
6 is_admin: DS.attr('boolean'),
7
8 roles: DS.hasMany('roles', { embedded: 'always' }),
9 office: DS.belongsTo('office', { async: true }),
10
11 fullName: function() {
12 return this.get('name') + this.get('surname');
13 }.property('name', 'surname'),
14
15 rolesList: function() {
16 return this.get('roles').map(function(role){
17 return role.get('name');
18 });
19 }.property('roles.@each')
20 });
I tipi consentiti sono: string, number, boolean, date
Modelli
8 roles: DS.hasMany('roles', { embedded: 'always' }),
9 office: DS.belongsTo('office', { async: true }),
I modelli possono essere in relazione tra loro:
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
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
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)
Controller
I controller “preparano” il modello e altri dati per l’uso nei template
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
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
Controller
Gli observer possono rimanere in “ascolto” di
cambiamenti negli attributi
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
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 });
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
Componenti
Componenti
• Formate da un file js di logica e gestione azioni e
un template
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
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)
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)
Componenti
1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
Componenti
1 import Ember from 'ember';
2 import moment from 'moment';
3
4 export default Ember.Component.extend({
5 classNames: ['col-md-1', 'text-center'],
6
7 isToday: function() {
8 return moment().format('YYYY-MM-DD') === moment(this.get(
9 'dayOfCurrentMonday')).add(this.get('dayOfWeek'), 'days').
10 format('YYYY-MM-DD');
11 }.property('dayOfCurrentMonday', 'dayOfWeek')
12 });
1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
Componenti
1 import Ember from 'ember';
2 import moment from 'moment';
3
4 export default Ember.Component.extend({
5 classNames: ['col-md-1', 'text-center'],
6
7 isToday: function() {
8 return moment().format('YYYY-MM-DD') === moment(this.get(
9 'dayOfCurrentMonday')).add(this.get('dayOfWeek'), 'days').
10 format('YYYY-MM-DD');
11 }.property('dayOfCurrentMonday', 'dayOfWeek')
12 });
1 {{#if isToday}}
2 {{dayOfWeek}} è oggi!
3 {{/if}}
1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
Componenti
1 import Ember from 'ember';
2 import moment from 'moment';
3
4 export default Ember.Component.extend({
5 classNames: ['col-md-1', 'text-center'],
6 classNameBindings: ['isToday:col-highlight'],
7 //qualcosa
8 });
1 {{yield}}
1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
2 //qualcosa
3 {{/timetracker-weekly-day-column}}
Le componenti prendono anche dei blocchi in input
Addon
emberaddons.com
ember install <addon>
Aggiungono funzionalità all’applicazione, ad esempio
template grafici (bootstrap), autenticazione, librerie
(moment.js, datepicker), paginazione, animazioni,
librerie personali, ecc.
Risorse utili
• guides.emberjs.com
• discuss.emberjs.com
• fromrailstoember.com
• ember-cli.com
• Ember.js su StackOverflow
• emberwatch.com
• Video da EmberConf 2015

Weitere ähnliche Inhalte

Ähnlich wie Introduzione a Ember.js

Corso WebApp iOS - Lezione 06: Web Development for iOS Devices
Corso WebApp iOS - Lezione 06:   Web Development for iOS DevicesCorso WebApp iOS - Lezione 06:   Web Development for iOS Devices
Corso WebApp iOS - Lezione 06: Web Development for iOS Devices
Andrea Picchi
 

Ähnlich wie Introduzione a Ember.js (20)

Novità di Asp.Net 4.0
Novità di Asp.Net 4.0Novità di Asp.Net 4.0
Novità di Asp.Net 4.0
 
Laravel Framework PHP
Laravel Framework PHPLaravel Framework PHP
Laravel Framework PHP
 
Creazione componenti con Vue js
Creazione componenti con Vue jsCreazione componenti con Vue js
Creazione componenti con Vue js
 
E suap - tecnologie client
E suap - tecnologie client E suap - tecnologie client
E suap - tecnologie client
 
jQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesignerjQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesigner
 
Hands on MVC - Mastering the Web
Hands on MVC - Mastering the WebHands on MVC - Mastering the Web
Hands on MVC - Mastering the Web
 
Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!
 
Applicazioni HTML5 Superveloci - Salvatore Romeo
Applicazioni HTML5 Superveloci - Salvatore RomeoApplicazioni HTML5 Superveloci - Salvatore Romeo
Applicazioni HTML5 Superveloci - Salvatore Romeo
 
Ddive Xpage852
Ddive Xpage852Ddive Xpage852
Ddive Xpage852
 
Tech Webinar: Test e2e per AngularJS e non solo
Tech Webinar: Test e2e per AngularJS e non soloTech Webinar: Test e2e per AngularJS e non solo
Tech Webinar: Test e2e per AngularJS e non solo
 
CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09
 
Corso WebApp iOS - Lezione 06: Web Development for iOS Devices
Corso WebApp iOS - Lezione 06:   Web Development for iOS DevicesCorso WebApp iOS - Lezione 06:   Web Development for iOS Devices
Corso WebApp iOS - Lezione 06: Web Development for iOS Devices
 
Maven - Aprile 2010
Maven - Aprile 2010Maven - Aprile 2010
Maven - Aprile 2010
 
WPF & LINQ: VB T&T Community After Hour @ Microsoft Days 08
WPF & LINQ: VB T&T Community After Hour @ Microsoft Days 08WPF & LINQ: VB T&T Community After Hour @ Microsoft Days 08
WPF & LINQ: VB T&T Community After Hour @ Microsoft Days 08
 
Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010
 
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
 
Installazione del cms alfresco
Installazione del cms alfrescoInstallazione del cms alfresco
Installazione del cms alfresco
 
Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
 
Working between the clouds
Working between the cloudsWorking between the clouds
Working between the clouds
 

Introduzione a Ember.js

  • 1. Testo Introduzione a Ember.js “A framework for creating ambitious web applications”
  • 2. Agenda Ember e ember-cli Template Routing Modelli e Ember-Data Controller Componenti Addons Risorse
  • 3. Ember.js “The web derives its power from the ability to bookmark and share URLs”
  • 4. Ember.js Da creatori/sviluppatori di jQuery, Rails, SproutCore “The web derives its power from the ability to bookmark and share URLs”
  • 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”
  • 9. Ciclo di sviluppo Release Beta Canary 1.13.0 2.0.0-beta1 2.0.0-canary+680f997e
  • 12. Ember-cli Command-line-interface per gestire un progetto Ember Asset pipeline con Broccoli (supporto per Handlebars, CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
  • 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
  • 18. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json
  • 19. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Configurazioni dell’applicazione
  • 20. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Gestione delle dipendenze del frontend (bower)
  • 21. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Gestione delle dipendenze del backend (Node.js)
  • 22. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Specifiche della compilazione di Broccoli (librerie, pacchetti, ecc.)
  • 23. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Ember 1.x: MVC Model: gestione dati (prob. ember-data) View (templates): presentazione dati (handlebars) Controller: manipolazione dati per il template
  • 24. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Ember 2.x: full-stack web framework Model: gestione dati (prob. ember-data) Components: componenti riusabili Templates: presentazione dati (HTMLbars) Router: recupero dati, gestione delle azioni dei template, salvataggio, redirect, ecc. (store, ember-data)
  • 25. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Specifiche delle rotte definisce gli URL (in Ember gli URL devono essere consistenti)
  • 26. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Componenti elementi riusabili nell’applicazione, composti da logica+template
  • 27. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Adapters logica di gestione delle API (come passare i dati, dove ottenerli, ecc.)
  • 28. Ember-cli - struttura file app/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.js config/environment.js bower.json ember-cli-build.js package.json Helpers funzioni riusabili (es. parsing di date con Moment.js)
  • 29. Ember-cli - generatori ember generate <generator-name> <options>
  • 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
  • 34. index.html 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title>MyNewApp</title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 10 {{content-for 'head'}} 11 12 <link rel="stylesheet" href="assets/vendor.css"> 13 <link rel="stylesheet" href="assets/my-new-app.css"> 14 15 {{content-for 'head-footer'}} 16 </head> 17 <body> 18 {{content-for 'body'}} 19 20 <script src="assets/vendor.js"></script> 21 <script src="assets/my-new-app.js"></script> 22 23 {{content-for 'body-footer'}} 24 </body> 25 </html>
  • 35. index.html 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title>MyNewApp</title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 10 {{content-for 'head'}} 11 12 <link rel="stylesheet" href="assets/vendor.css"> 13 <link rel="stylesheet" href="assets/my-new-app.css"> 14 15 {{content-for 'head-footer'}} 16 </head> 17 <body> 18 {{content-for 'body'}} 19 20 <script src="assets/vendor.js"></script> 21 <script src="assets/my-new-app.js"></script> 22 23 {{content-for 'body-footer'}} 24 </body> 25 </html> vendor.css e vendor.js contengono css e js delle librerie esterne
  • 36. index.html 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title>MyNewApp</title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 10 {{content-for 'head'}} 11 12 <link rel="stylesheet" href="assets/vendor.css"> 13 <link rel="stylesheet" href="assets/my-new-app.css"> 14 15 {{content-for 'head-footer'}} 16 </head> 17 <body> 18 {{content-for 'body'}} 19 20 <script src="assets/vendor.js"></script> 21 <script src="assets/my-new-app.js"></script> 22 23 {{content-for 'body-footer'}} 24 </body> 25 </html>
  • 37. index.html 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title>MyNewApp</title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 10 {{content-for 'head'}} 11 12 <link rel="stylesheet" href="assets/vendor.css"> 13 <link rel="stylesheet" href="assets/my-new-app.css"> 14 15 {{content-for 'head-footer'}} 16 </head> 17 <body> 18 {{content-for 'body'}} 19 20 <script src="assets/vendor.js"></script> 21 <script src="assets/my-new-app.js"></script> 22 23 {{content-for 'body-footer'}} 24 </body> 25 </html> my-new-app.css e my-new-app.js contengono css e js dell’app
  • 38. application.hbs 1 <h2 id="title">Welcome to Ember.js</h2> 2 3 {{outlet}}
  • 39. 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
  • 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
  • 45. Modello associato Ogni rotta ha un modello associato
  • 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!)
  • 50. Definire un modello 1 import DS from 'ember-data'; 2 3 export default DS.Model.extend({ 4 name: DS.attr('string'), 5 surname: DS.attr('string'), 6 is_admin: DS.attr('boolean'), 7 8 roles: DS.hasMany('roles', { embedded: 'always' }), 9 office: DS.belongsTo('office', { async: true }), 10 11 fullName: function() { 12 return this.get('name') + this.get('surname'); 13 }.property('name', 'surname'), 14 15 rolesList: function() { 16 return this.get('roles').map(function(role){ 17 return role.get('name'); 18 }); 19 }.property('roles.@each') 20 }); I tipi consentiti sono: string, number, boolean, date
  • 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)
  • 55. Controller I controller “preparano” il modello e altri dati per l’uso nei template
  • 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
  • 58. Controller Gli observer possono rimanere in “ascolto” di cambiamenti negli attributi
  • 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
  • 63. Componenti • Formate da un file js di logica e gestione azioni e un template
  • 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)
  • 68. Componenti 1 import Ember from 'ember'; 2 import moment from 'moment'; 3 4 export default Ember.Component.extend({ 5 classNames: ['col-md-1', 'text-center'], 6 7 isToday: function() { 8 return moment().format('YYYY-MM-DD') === moment(this.get( 9 'dayOfCurrentMonday')).add(this.get('dayOfWeek'), 'days'). 10 format('YYYY-MM-DD'); 11 }.property('dayOfCurrentMonday', 'dayOfWeek') 12 }); 1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
  • 69. Componenti 1 import Ember from 'ember'; 2 import moment from 'moment'; 3 4 export default Ember.Component.extend({ 5 classNames: ['col-md-1', 'text-center'], 6 7 isToday: function() { 8 return moment().format('YYYY-MM-DD') === moment(this.get( 9 'dayOfCurrentMonday')).add(this.get('dayOfWeek'), 'days'). 10 format('YYYY-MM-DD'); 11 }.property('dayOfCurrentMonday', 'dayOfWeek') 12 }); 1 {{#if isToday}} 2 {{dayOfWeek}} è oggi! 3 {{/if}} 1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}}
  • 70. Componenti 1 import Ember from 'ember'; 2 import moment from 'moment'; 3 4 export default Ember.Component.extend({ 5 classNames: ['col-md-1', 'text-center'], 6 classNameBindings: ['isToday:col-highlight'], 7 //qualcosa 8 }); 1 {{yield}} 1 {{#timetracker-weekly-day-column dayOfCurrentMonday=dayOfCurrentMonday dayOfWeek=5}} 2 //qualcosa 3 {{/timetracker-weekly-day-column}} Le componenti prendono anche dei blocchi in input
  • 71. Addon emberaddons.com ember install <addon> Aggiungono funzionalità all’applicazione, ad esempio template grafici (bootstrap), autenticazione, librerie (moment.js, datepicker), paginazione, animazioni, librerie personali, ecc.
  • 72. Risorse utili • guides.emberjs.com • discuss.emberjs.com • fromrailstoember.com • ember-cli.com • Ember.js su StackOverflow • emberwatch.com • Video da EmberConf 2015