Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Intro to Ember.JS 2016

541 visualizaciones

Publicado el

Intro to Ember.JS javascript framework. An introduction to coding on the Ember javascript framework

Publicado en: Software
  • Sé el primero en comentar

Intro to Ember.JS 2016

  1. 1. INTRO TO EMBER.JSSandino Núñez @sandinosaso https://github.com/sandinosaso
  2. 2. YES, ANOTHER JAVASCRIPT FRAMEWORK
  3. 3. EMBER.JS
  4. 4. WHAT IS EMBER.JS ➤ A framework for creating ambitious web application ➤ Built for productivity (provides architecture) ➤ Opinionated (sometimes perceived as difficult to learn) ➤ Convention over Configuration (besides awesome!)
  5. 5. EMBER IN THE WILD http://emberjs.com/ember-users/
  6. 6. Simple apps can use simple tools
  7. 7. APPS NEEDS ➤ Keep it organized ➤ Modularize your code ➤ Separate concerns ➤ Establish conventions for smooth teamwork ➤ Keep it testable ARCHITECTUREBIG
  8. 8. EMBER CORE CONCEPTS ➤ Classes and Instances ➤ Computed Properties ➤ Bindings ➤ Templates ➤ Route ➤ Models ➤ Components ➤ Data Down - Actions Up ➤ Lots of other features - we’ll just barely scratch the surface in today’s session
  9. 9. EMBER OBJECT➤ Base “class” that almost every object should inherit from ➤ Contains …
  10. 10. EMBER OBJECT1 import Ember from 'ember'; 2 3 let Person = Ember.Object.extend({ 4 say(message) { 5 alert(message); 6 } 7 }); 8 9 let Bob = Person.create(); 10 Bob.say('Hello World'); 11 // alerts "Hello World" 12 13 let Man = Person.extend({ 14 say(message) { 15 message += ', says the man.'; 16 this._super(message); 17 } 18 }); 19 20 let Tom = Man.create(); 21 Tom.say('Hello World');
  11. 11. EMBER OBJECT ➤ Obj.create() instead of new instances ➤ Obj.extend() for single inheritance (mixins exists as well) ➤ this._super() calls overridden implementation ➤ Obj.reopen() to edit class definition ➤ Obj.get(‘key’) and Obj.set(‘key’) ➤ Allows dynamically created property values ➤ Object can listen for properties changes ➤ Use of .setProperties({ key: value }) for multiple at time.
  12. 12. COMPUTED PROPERTIES➤ Used to build a property that depends on other properties ➤ Provide any property key you access and the property value will be recomputed if change ➤ Should not contain application behavior, and should generally not cause any side-effects when called. 1 import Ember from 'ember'; 2 3 let Person = Ember.Object.extend({ 4 firstName: '', 5 lastName: '', 6 7 fullName: Ember.computed('firstName', 'lastName', function() { 8 return this.get('firstName') + ' ' + this.get('lastName'); 9 }) 10 }); 11 12 let bob = Person.create({ 13 firstName: 'Bob', 14 lastName: 'Esponja' 15 }); 16 17 bob.get('fullName'); 18 // "Bob Esponja"
  13. 13. COMPUTED PROPERTIES (advanced usage) 1 export default Ember.Component.extend({ 2 selectedTodo: null, 3 4 todos: [ 5 Ember.Object.create({ isDone: true }), 6 Ember.Object.create({ isDone: false }), 7 Ember.Object.create({ isDone: true }) 8 ], 9 10 // Custom 11 incomplete: Ember.computed('todos.@each.isDone', function() { 12 var todos = this.get('todos'); 13 return todos.filterBy('isDone', false); 14 }), 15 16 // Using defined macro 17 incomplete: Ember.computed.filterBy('todos', 'isDone', false), 18 19 indexOfSelectedTodo: Ember.computed('selectedTodo', 'todos.[]', function() { 20 return this.get('todos').indexOf(this.get('selectedTodo')); 21 }) 22 });
  14. 14. BINDINGS ➤ Unlike most other frameworks that include some sort of binding implementation, bindings in Ember can be used with any object. ➤ A one-way binding only propagates changes in one direction, using computed.oneWay() 1 wife = Ember.Object.create({ 2 householdIncome: 80000 3 }); 4 5 Husband = Ember.Object.extend({ 6 householdIncome: Ember.computed.alias('wife.householdIncome') 7 }); 8 9 husband = Husband.create({ 10 wife: wife 11 }); 12 13 husband.get('householdIncome'); // 80000 14 15 // Someone gets raise. 16 wife.set('householdIncome', 90000); 17 husband.get('householdIncome'); // 90000
  15. 15. TEMPLATES ➤ Uses Handlebars + Ember helpers ➤ Ember adds partial, render, view and control helpers ➤ Each template is backed by a model ➤ They include helpers such as: other templates, if else, loops, formatting helpers, expressions like {{model.firstName}}, outlets (which are placeholders), components 1 <div id="main"> 2 <div class="container-fluid"> 3 4 {{outlet}} 5 6 </div> 7 </div>
  16. 16. ROUTES ➤ Url representation of your application’s objects, telling the template ➤ The router.js file defines the mapping between routes/urls 1 import Ember from 'ember'; 2 import config from './config/environment'; 3 4 const Router = Ember.Router.extend({ 5 location: config.locationType 6 }); 7 8 Router.map(function() { 9 this.route('login'); 10 11 this.route('patients', function() { 12 this.route('new'); 13 this.route('edit', { path: 'edit/:id' }); 14 this.route('view', { path: 'view/:id' }); 15 this.route('audit', { path: 'audit/:id' }); 16 17 this.route('activities', { path: '/activities/:patient_id' }, function() { 18 this.route('new', { path: 'new' }); 19 this.route('view', { path: 'view/:id' }); 20 }); 21 22 this.route('events', { path: '/events/:patient_id' }, function() { 23 this.route('new', { path: '/new/:eventType' }); 24 this.route('view', { path: '/view/:id' }); 25 }); 26 27 }); 28 }); 29 30 export default Router;
  17. 17. 1 import Ember from 'ember'; 2 3 export default Ember.route.extend({ 4 5 model: function() { 6 return [ 7 { 8 title: “London Palace" 9 }, 10 { 11 title: "Eiffel Tower" 12 } 13 ]; 14 } 15 }); ROUTING(implementation of a base route) The model usually is a record. The result of a query to ember-data store 1 import Ember from 'ember'; 2 3 export default Ember.route.extend({ 4 5 model(params) { 6 var url = 'https://api.github.com/repos/' + params.repo_id; 7 return Ember.$.getJSON(url); 8 } 9 }); The model can be a POJO 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 }); The result of an ajax call
  18. 18. ROUTING(returning multiple models) 1 import Ember from 'ember'; 2 3 export default Ember.route.extend({ 4 5 setupController(controller, model) { 6 controller.setProperties({ 7 patient: model.patient, 8 products: model.products 9 }); 10 11 set(controller, 'isLoading', false); 12 }, 13 14 model(params) { 15 return RSVP.hash({ 16 patient: this.store.findRecord('patient', params.id), 17 products: this.store.findAll('product') 18 }); 19 } 20 });
  19. 19. ROUTES ➤ The route queries the model and makes it available in the controller and templates ➤ When the template or models being shown to the user changes, Ember automatically keeps the url in the browser’s address bar up-to-date ➤ This means that at any point, users are able to share the URL of your app ➤ Ember Add-on for Chrome and Firefox let you inspect routes / data / promises ➤ error and loading routes automatically created and used on model loading and error states
  20. 20. MODELS ➤ Define a mapping to the application data ➤ Has default types: string, number, boolean, date. Supports customs types 1 import Ember from 'ember'; 2 import Model from 'ember-data/model'; 3 import attr from 'ember-data/attr'; 4 import { belongsTo, hasMany } from 'ember-data/relationships'; 5 6 const { computed } = Ember; 7 8 export default Model.extend({ 9 'name': attr('string'), 10 'surname': attr('number'), 11 'is_admin': attr('boolean'), 12 13 'roles': hasMany('roles', { embedded: 'always'}), 14 'office': belongsTo('office', { async: 'true' }), 15 16 fullName: computed('name', 'surname', () => { 17 return this.get('name') + ' ' + this.get('surname'); 18 }), 19 20 roleList: computed('roles.@each', () => { 21 return this.get('roles').map((role) => { 22 return role.get('name'); 23 }) 24 }) 25 });
  21. 21. MODELS ➤ In the first case the data comes from backend in the model itself (payload) ➤ In the second case the model only contains the ‘ID’ of the related model and is loaded asynchrony with an specific call when required. 13 'roles': hasMany('roles', { embedded: 'always'}), 14 'office': belongsTo('office', { async: 'true' }), (relationships) You can also define custom attr options, for example (readOnly): 16 'entityId': attr('string', { readOnly: true }), 17 'entityType': attr('string', { readOnly: true }),
  22. 22. MODELS ➤ You can define custom types to fit any kind of data ➤ Makes it easy to maintain as you only need to change in one place 1 // app/transforms/utc.js 2 import DS from 'ember-data'; 3 import moment from 'moment'; 4 5 export default DS.Transform.extend({ 6 serialize(value) { 7 let formatedDate = moment.utc(value).format('YYYY-MM-DDTHH:mm:ss', 'en'); 8 return formatedDate; 9 }, 10 11 deserialize(value) { 12 return value; 13 } 14 }); 1 export default Model.extend({ 2 'productId': attr('number'), 3 'eventTypeID': attr('number'), 4 'reasonSVID': attr('string'), 5 'notes': attr('string'), 6 7 'eventDate': attr('utc', { defaultValue: () => new Date() }) 8 }
  23. 23. ADAPTER / SERIALIZER➤ By default ember-data uses JSON-API format ➤ You can override default behavior either application level or for particular models (fit any backend data even legacy one !!)
  24. 24. ➤ In Ember Data, the Adapter determines how data is persisted to a backend data store, such as the URL format and headers for a REST API. ➤ You can change default functionality (if your backend conventions differ from ember-data assumptions) by extending it ADAPTER(customization example) 1 import Ember from 'ember'; 2 import DS from 'ember-data'; 3 4 export default DS.JSONAPIAdapter.extend({ 5 host: 'https://api.example.com', 6 namespace: 'api', 7 8 session: Ember.inject.service('session'), 9 10 headers: Ember.computed('session.authToken', function() { 11 return { 12 'API_KEY': this.get('session.authToken'), 13 'ANOTHER_HEADER': 'Some header value' 14 }; 15 }) 16 });
  25. 25. ➤ In Ember Data, serializers format the data sent to and received from the backend store. SERIALIZER(customization example)
  26. 26. ADAPTER / SERIALIZER (customization/ methods)
  27. 27. COMPONEN TS➤ A completed isolated view that has no access to the surrounding context ➤ A great way to build reusable components for your application ➤ routable-components will be the future
  28. 28. DATA DOWN! ACTIONS UP!➤ DDAU - single data flow (hence unidirectional) ➤ Apps easier to reason about ➤ Improves performance (GoodBye MVC)
  29. 29. DEMO - SHOWCASE - TIME

×