Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ember.js. Aplicaciones complejas en el cliente

Pepe Cano
April 27, 2012

Ember.js. Aplicaciones complejas en el cliente

Introducción a Ember.js

Pepe Cano

April 27, 2012
Tweet

More Decks by Pepe Cano

Other Decks in Programming

Transcript

  1. "It's like you build something and people experience it in

    all these different places. So making it so you can build once and kind of have it in a lot of these different places I think it's going to be very valuable." Mark Zuckerberg (CEO de Facebook), Octubre 2010.
  2. "We can do 95 percent of what we want to

    do with HTML5" Thom Cummings (VP marketing de Soundcloud), Febrero 2012.
  3. "This is the best time ever to be a software

    developer" Steve Ballmer (CEO de Microsoft), Septiembre 2011.
  4. Ember.js JavaScript framework for creating ambitious web applications that eliminates

    boilerplate and provides a standard application architecture
  5. Frameworks MVC JS Bindings Plantillas HTML Vistas jerárquicas Interoperabilidad Backbone.js

    Spine.js Knockout.js Batman.js Serenade.js Angular.js Ember.js Sproutcore > 1.5 Cappuchino Thanks to @tchak13
  6. Computed, bindings y observers Person = Ember.Object.extend({ firstName: null, lastName:

    null, fullName: function() { return this.get(' firstName') + ' ' + this.get(' lastName'); }.property('firstName', 'lastName'), fullNameChanged: function() { //do whatever u want }.observes('fullName') }); App.selectedBrandsController = Em.ArrayController.create({ content: null, selectedCategory Binding: Em.Binding.oneWay('App. categoryController.selectedItem') }); Mantiene una lista de sus dependientes y notifica de los cambios
  7. Modelos Define el esquema del dominio y contiene los datos

    persistentes App.Brand = DS.Model.extend({ name: DS.attr('string'), marked: DS.attr('boolean') });
  8. Modelos - Ember Data Ember-data (ORM en el lado del

    cliente) para REST API • Define relaciones ( hasMany, hasOne, belongsTo ) • Query ( find, findQuery, findAll ) • Create, update, delete • Backend independiente
  9. Proxies App.selectedUser = Em.Object.create({ content: null, hasBeenVisited: false }); App.arrayItemController

    = Em.ArrayController.create({ content: null, remaining: function() { var content = this.get('content'); return content.filterProperty('isDone',false).get('length'); }.property('[email protected]') });
  10. Coordinadores (ember-states) Gestiona los distintos estados y eventos del usuario/aplicación

    • StateManager ( define los estados ) • States ( send, goToState ) start search home result if X else
  11. Vistas Gestiona la representacion de los datos y eventos del

    usuario App.coolView = Ember.View.create({ render: function(buffer) { buffer.push("<b>This view is so cool!</b>"); } }); my_view.js App.myView = Em.View.create({ userBinding: Em.Binding.oneWay(‘App.userController.content’), templateName: ‘my_view’ }); my_view.handlebars {{#if user}} Welcome back, <b>{{user.firstName}} {{user.lastName}}</b>! {{view App.LanguageIconView contentBinding="user.language" }} {{/if}}
  12. Vistas view.appendTo('#container'); view.remove(); var view = Em.ContainerView.create({ childViews: [‘label’, ‘input’,

    ‘button’], label: App.LabelView, input: App.InputView, button: App.ButtonView });
  13. Resultado <div id="category_list" class="ember-view"> <img class="ember-view category is-selected" src="category1.png" ></img>

    <img class="ember-view category" src="category2.png"></img> <img class="ember-view category" src="category3.png"></img> <img class="ember-view category" src="category4.png"></img> <img class="ember-view category" src="category5.png"></img> </div>
  14. Modelos models/category.js Yn.Category = DS.Model.extend({ name: DS.attr('string'), picture: DS.attr('string'), order:

    DS.attr('number') }); init/app.js var categories = Yn.store.find(Yn.Category, {order_by: 'order'});
  15. Proxies controllers/category.js App.categoriesController = Em.ArrayController.create({ content: null }); App.categoryController =

    Em.Object.create({ selectedItem: null }); init/app.js App.categoriesController.set('content', categories); App.categoryController.set('selectedItem', categories.get ('firstObject') );
  16. Vista de la lista de categorías views/category.js App.CategoryListView = Em.CollectionView.extend({

    elementId: ' category_list', contentBinding: Em.Binding.oneWay('App.categoriesController. content'), itemViewClass: App.CategoryView }); <div id="category_list" class="ember-view"> ... </div>
  17. Vista de la categoría App.CategoryView = Em.View.extend({ tagName: 'img', classNames:

    ['category'], attributeBindings: ['src'], src: Em.computed(function(){ return this.getPath('content.picture') ); }).property( 'content.picture') classNameBindings: ['is_selected'], selectedCategoryBinding: Em.Binding.oneWay(‘App. selectedCategory.content’), is_selected: Em.computed(function(){ return ( Em.getPath(this, 'selectedCategory.id') === this.getPath('content.id') ); }).property( 'content', 'selectedCategory') }); <img class="ember-view category is-selected" src="category1.png" ></img>
  18. Eventos de usuario views/category.js App.CategoryView = Em.View.extend(App.bTap, { .... bTap:

    function(){ App.manager.send(' selectedCategory ', this.get(' content') ); } }); states/category.js App.CategoryState = Em.State.extend({ selectedCategory: function( stateManager, category ) { App.categoryController.set('selectedItem', category); } });
  19. Resultado <div id="category_list" class="ember-view"> <img class="ember-view category" src="category1.png"></img> <img class="ember-view

    category" src="category2.png"></img> <img class="ember-view category is-selected" src="category3.png" ></img> <img class="ember-view category" src="category4.png"></img> <img class="ember-view category" src="category5.png"></img> </div>
  20. Vista de la categoría App.CategoryView = Em.View.extend({ tagName: 'img', classNames:

    ['category'], attributeBindings: ['src'], src: Em.computed(function(){ return this.getPath('content.picture') ); }).property( 'content.picture') classNameBindings: ['is_selected'], selectedCategoryBinding: Em.Binding.oneWay(‘App. selectedCategory.content’), is_selected: Em.computed(function(){ return ( Em.getPath(this, 'selectedCategory.id') === this.getPath('content.id') ); }).property( 'content', 'selectedCategory') }); <img class="ember-view category is-selected" src="category1.png" ></img>
  21. Definiendo vistas Yn.ActionButtonView = Em.ContainerView.extend(Yn.Btap, {..}); "Each rule set that

    we add to our style sheet creates an ever increasing connection between the CSS and the HTML." Jonathan Snook ("Evolving guide to CSS architecture for sites small and large." )
  22. Sproutcore / Ember-touch Librería para reconocer diferentes gestos (Influencia iOS

    UIKit) view = Em.View.create({ swipeOptions: { direction: Em.OneGestureDirection.Right, cancelPeriod: cancelPeriod, swipeThreshold: swipeThreshold, simultaneously: true }, swipeStart: function(recognizer) { }, swipeChange: function(recognizer) {}, swipeEnd: function(recognizer) {}, swipeCancel: function(recognizer) {} });
  23. Gestionando los estados Relacionando los estados con la vistas principales

    App.GiftManager = Ember.StateManager.extend({ initialState: 'brand', brand: App.GiftBrandState.create(), city: App.GiftCityState.create(), product: App.GiftProductState.create(), product_info: App.GiftProductInfoState.create(), map: App.GiftMapState.create(), map_error: App.GiftMapErrorState.create(), contact: App.GiftContactState.create(), popup: App.GiftPopupState.create() });
  24. Herramientas de construcción rake-pipeline + makefile Minimizar código Compilar Pre-procesadores

    CSS Empaquetar ficheros Carga asíncrono de librerías/JS Cargar scripts en el orden adecuado …
  25. Siguientes pasos Incluir nuevos patrones Incrementar la adopción y comunidad

    Soporte para distintos navegadores/dispositivos móviles ...