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

Ember - Por que você ainda não está usando?

Ember - Por que você ainda não está usando?

Danilo Vaz

August 14, 2017
Tweet

More Decks by Danilo Vaz

Other Decks in Technology

Transcript

  1. Um framework para criar aplicações web ambiciosas Criado pensando na

    produtividade do desenvolvedor Opinado e alinhado com os Padrões Web Convenção ao invés de configuração Core Team trabalhando em apps reais e robustos
  2. It's more important to reduce the effort of maintenance than

    it's to reduce the effort of implementation. Max Kanat-Alexander, Code Quality
  3. //app/models/user.js import Ember from 'ember'; import DS from 'ember-data'; export

    default DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), fullName: Ember.computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; }) });
  4. Renderiza um template Carrega um model e disponibiliza para o

    template Redireciona para uma nova rota Manipula ações que envolvem mudanças em um model
  5. //app/router.js Router.map(function() { this.route('posts', { path: '/posts' }); }); //app/router.js

    Router.map(function() { this.route('posts', { path: '/posts' }, function() { this.route('new'); }); }); Rotas Rotas Aninhadas
  6. //app/router.js Router.map(function() { this.route('posts', { path: '/posts' }, function() {

    this.route('new'); this.route('post', { path: '/post/:post_id' }); }); }); //app/routes/post.js import Ember from 'ember'; export default Ember.Route.extend({ model(params) { return this.get('store').findRecord('post', params.post_id); } });
  7. //app/templates/application.hbs <p>Olá, <strong>{{firstName}} {{lastName}}</strong>!</p> <p>Seja bem vindo ao Hackers House!</p>

    Handlebars Helpers //app/helpers/sum.js import Ember from 'ember'; export function sum(params) { return params.reduce((a, b) => { return a + b; }); }; export default Ember.Helper.helper(sum); //app/templates/application.hbs <p>Total: {{sum 1 2 3}}</p>
  8. Built-in Helpers {{#if authenticated}} <p>Bem vindo, <strong>{{user.firstName}} {{user.lastName}}</strong>!</p> {{else}} <p>Por

    favor, é necessário fazer o login para acessar essa página.</p> {{/if}} <ul> {{#each users as |user|}} <li>{{user.firstName}}!</li> {{/each}} </ul> {{input type="text" value=firstName disabled=entryNotAllowed size="50"}} {{input type="checkbox" name="isAdmin" checked=isAdmin}} {{textarea value=description cols="80" rows="6"}}
  9. Actions //app/components/single-post.hbs <p><button {{action "select" post}}>✓</button> {{post.title}}</p> //app/components/single-post.js import Ember

    from 'ember'; export default Ember.Component.extend({ actions: { select(post) { console.log(post.get('title')); } } });
  10. //HTML renderizado <nav class="nav-bar"> <ul> <li><a href="/" id="ember323" class="active ember-view">Início</a></li>

    <li><a href="/posts" id="ember324" class="ember-view">Posts</a></li> </ul> </nav> //app/components/navigation-bar.js import Ember from 'ember'; export default Ember.Component.extend({ classNames: ['nav-bar'], tagName: 'nav' }); //app/templates/components/navigation-bar.hbs <ul> <li>{{#link-to "home"}}Início{{/link-to}}</li> <li>{{#link-to "post"}}Posts{{/link-to}}</li> </ul> + = //app/templates/application.hbs {{navigation-bar}}
  11. Só precisamos gerar um Controller se desejarmos customizar suas propriedades

    ou providenciar alguma action. Caso contrário, se você não gerar um, o Ember irá provindenciar uma instância de um Controller em run time.
  12. //app/templates/blog-post.hbs <h1>{{model.title}}</h1> <h2>Autor: {{model.author}}</h2> <div class='intro'> {{model.intro}} </div> <hr> {{#if

    isExpanded}} <button {{action "toggleBody"}}>Ver menos</button> <div class="body"> {{model.body}} </div> {{else}} <button {{action "toggleBody"}}>Ver mais</button> {{/if}} //app/controllers/blog-post.js import Ember from 'ember'; export default Ember.Controller.extend({ actions: { toggleBody() { this.toggleProperty('isExpanded'); } } });
  13. //app/models/post.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'),

    body: DS.attr('string'), published: DS.attr('boolean', { defaultValue: false }), createdAt: DS.attr('date', { defaultValue() { return new Date(); } }) });
  14. //app/models/user.js import DS from 'ember-data'; export default DS.Model.extend({ name: DS.attr('string'),

    profile: DS.belongsTo('profile') }); //app/models/profile.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'), user: DS.belongsTo('user') }); One-to-One
  15. //app/models/post.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'),

    body: DS.attr('string'), published: DS.attr('boolean', { defaultValue: false }), createdAt: DS.attr('date', { defaultValue() { return new Date(); } }) comments: DS.hasMany('comment') }); //app/models/comment.js import DS from 'ember-data'; export default DS.Model.extend({ text: DS.attr('string'), post: DS.belongsTo('post') }); One-to-Many
  16. //app/models/post.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'),

    body: DS.attr('string'), published: DS.attr('boolean', { defaultValue: false }), createdAt: DS.attr('date', { defaultValue() { return new Date(); } }) comments: DS.hasMany('comment'), tags: DS.hasMany('tag') }); //app/models/tag.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'), post: DS.hasMany('post') }); Many-to-Many
  17. let post = store.createRecord('post', { title: 'Ember.js no Hackers House',

    body: 'Lorem ipsum' }); // => chamada POST em '/posts' post.save(); // => chamada GET em /posts let posts = this.get('store').findAll('post'); // => chamada GET em /posts/1 let post = this.get('store').findRecord('post', 1); Create Read
  18. this.get('store').findRecord('user', 1).then(function(response) { // após o dado ter sido carregado

    response.set('firstName', "Danilo Vaz"); }); // => chamada DELETE em /posts/2 store.findRecord('post', 2, { backgroundReload: false }).then(function(post) { post.destroyRecord(); }); Update Delete
  19. // => Nenhuma requisição web é feita. Busca no Storage.

    let posts = this.get('store').peekAll('post'); peekAll peekRecord // => Nenhuma requisição web é feita. Busca no Storage. let post = this.get('store').peekRecord('post', 1);
  20. //app/adapters/application.js import DS from 'ember-data'; export default DS.JSONAPIAdapter.extend({ session: Ember.inject.service('session'),

    host: 'https://api.meusite.com.br', headers: Ember.computed('session.authToken', function() { return { 'TOKEN': this.get('session.authToken'), 'OUTRO-HEADER': 'Hackers House 2017' }; }) });
  21. { "data": { "id": "1", "type": "product", "attributes": { "name":

    "My Product", "amount": 100, "currency": "SEK" } } } { "data": { "id": "1", "type": "product", "attributes": { "name": "My Product", "cost": { "amount": 100, "currency": "SEK" } } } } import DS from 'ember-data'; export default DS.JSONAPISerializer.extend({ serialize(snapshot, options) { let json = this._super(...arguments); json.data.attributes.cost = { amount: json.data.attributes.amount, currency: json.data.attributes.currency }; delete json.data.attributes.amount; delete json.data.attributes.currency; return json; }, });