Introduzione a Ember.js
-
Upload
tommaso-visconti -
Category
Internet
-
view
587 -
download
0
Transcript of Introduzione a Ember.js
Testo
Introduzione a Ember.js“A framework for creating ambitious web applications”
AgendaEmber 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 Canary1.13.0 2.0.0-beta1 2.0.0-canary+680f997e
Ember-cli
Ember-cliCommand-line-interface per gestire un progetto Ember
Ember-cliCommand-line-interface per gestire un progetto Ember
Asset pipeline con Broccoli (supporto per Handlebars, CoffeeScript, Sass, Less, minifier, uglifier, ecc.)
Ember-cliCommand-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-cliCommand-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-cliCommand-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-cliCommand-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 & runningnpm install -g ember-cli bower phantomjsember new my-new-appcd my-new-appnpm install && bower installember server
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Configurazioni dell’applicazione
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Gestione delle dipendenze del frontend (bower)
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Gestione delle dipendenze del
backend (Node.js)
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Specifiche della compilazione di Broccoli (librerie, pacchetti, ecc.)
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.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 fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.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 fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Specifiche delle rotte definisce gli URL (in Ember gli URL
devono essere consistenti)
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Componenti elementi riusabili
nell’applicazione, composti da logica+template
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.json
Adapters logica di gestione delle API (come
passare i dati, dove ottenerli, ecc.)
Ember-cli - struttura fileapp/ — adapters/ — components/ — controllers/ — helpers/ — models/ — routes/ — styles/ — templates/ — app.js — index.html — router.jsconfig/environment.jsbower.jsonember-cli-build.jspackage.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 - generatoriember 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 associatoOgni rotta ha un modello associato
Modello associatoOgni 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 associatoOgni 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 });
StoreLo 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 backendmodel.save().catch(function() {// ops! Torniamo indietro model.rollback();});
StoreLo 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 backendmodel.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)
ControllerI 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
ControllerGli 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