sábado, 23 de janeiro de 2016

REST - YO facilitando a vida Angular

O que mais gosto na tecnologia é como as coisas mudam rápido. Se dissesse a 10 anos que o JavaScript causaria uma revolução nas páginas Web, provavelmente seria taxado de louco. Atualmente estamos vendo não apenas a aceitação dessa linguagem, mas o seu completo domínio.

Obviamente seus filhos é que estão ganhando o mercado. O Angular.js da Google é sem dúvida a "menina loirinha e dos olhos azuis" desses filhos. Angular é prático, rápido, fácil de usar e com uma infinidade de recursos - publiquei uma série de artigos em 2013 sobre este framework. Porém nesse ambiente um único detalhe deixa a desejar: a montagem de um projeto consistente que permita crescer. Essa parte está completamente amarrada a capacidade e conhecimento do arquiteto.

Para resolver este problema, encontramos o Yo. Um framework com a função de manter a arquitetura de seu projeto voltada as boas práticas do mercado, e assim podemos nos preocupar somente com a codificação.


Criar uma aplicação Angular com o Yo é muito fácil e arquiteturalmente falando muito prática, já seguindo as regras de um bom modelo MVC. Vamos montar uma aplicação como forma de entendermos como funciona.

Instalação

Este tutorial está criado para o Ubuntu (meu sistema), mas acredito que facilmente poderá ser adaptado para qualquer sistema.
$ sudo npm install -g yo generator-angular generator-karma grunt-cli bower
Instalamos através do npm o yo, o Gerador do Angular, arquivos necessários para acessarmos o servidor Grunt e o gerenciador de dependências Bower. A diretiva -g indica que serão instalados de forma global para que não necessitemos mais instalá-los (esse passo só será realizado esta vez). Importante: Instale o Git.

Criar a Aplicação

Uma vez que todos os aplicativos estão instalados podemos criar uma aplicação.
$ mkdir coffeshop
$ cd coffeshop
$ yo angular:app coffeshop
Criamos uma pasta para abrigarmos o projeto. Acessamos esta pasta. Criamos os arquivos necessários para a aplicação - Responda "N" para a troca do Grunt pelo Gulp e para o uso do Sass.

Por fim iniciamos o servidor Grunt com o seguinte comando:
$ grunt server
E a seguinte página inicial será mostrada:


O servidor Grunt é excelente, permite o hot deploy de sua aplicação, isto é, ao realizar mudanças a página é dinamicamente reprocessada sem a necessidade de reiniciar o servidor. Pronto, já foi criado toda a estrutura necessário para se começar a trabalhar com o Angular, Bootstrap e Karma - este último é um framework de testes unitários que verifica os erros de suas páginas. Para executar os testes com o Karma é necessário baixar os pacotes localmente, para isso digite Ctrl+C para interromper o servidor e instale os pacotes com o comando:
$ npm install karma jasmine-core phantomjs phantomjs-prebuild
Execute o teste com o seguinte comando:
$ grunt test
Poderíamos parar por aqui, mas quero iniciar um pequeno aplicativo, inicie novamente o servidor do Grunt. Sou louco por café, para se ter uma ideia do quanto comprei uma dessas máquinas italianas para preparar um bom Cappuccino e todas suas variações.

Para o primeiro passo, baixe as imagens necessárias (no link abaixo) e descompacte-as na pasta \app\images da aplicação.

Baixar as images

Segundo passo, modifique o arquivo main.js que se encontra na pasta \app\scripts\controller para a seguinte codificação:
'use strict';

/**
 * @ngdoc function
 * @name coffeshopApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the coffeshopApp
 */
angular.module('coffeshopApp')
  .controller('MainCtrl', function ($scope) {
    $scope.coffes = [
      {nome:"Affogato", imagem:"cafe01", descr:"Sorvete de baunilha com um pouco de expresso"},
      {nome:"Americano", imagem:"cafe02", descr:"Expresso diluído com água quente"},
      {nome:"Black coffe", imagem:"cafe03", descr:"Café sem a adição de leite"},
      {nome:"Cafe au Lait", imagem:"cafe04", descr:"Partes iguais de café e leite"},
      {nome:"Cafe Breva", imagem:"cafe05", descr:"Expresso servido com meio a meio"},
      {nome:"Cafe Latte", imagem:"cafe06", descr:"Curto expresso com leite quente e, um pouco de espuma de leite"},
      {nome:"Cappuccino", imagem:"cafe07", descr:"Curto expresso com a combinação de leite quente e fervido. Cappuccino possui uma larga espuma de leite com um café com leite"},
      {nome:"Double", imagem:"cafe08", descr:"Duas partes de expresso usados como um drink expresso"},
      {nome:"Dry Cappuccino", imagem:"cafe09", descr:"Cappuccino feito com um pouco de expuma de leite"},
      {nome:"Expresso", imagem:"cafe10", descr:"Leite quente é forçado por um fino cano com café para produzir uma forte bebida"},
      {nome:"Expresso con Panna", imagem:"cafe11", descr:"Uma porção de expresso com um pouco de espuma de creme"},
      {nome:"Expresso Macchiato", imagem:"cafe12", descr:"Uma porção de expresso com um pouco de espuma de leite"},
      {nome:"Flat White", imagem:"cafe13", descr:"Expresso com leite vaporizado derramado de um jarro quente com um pouco de expresso"},
      {nome:"Flavoured Coffee", imagem:"cafe14", descr:"Blend de café com xaropes de especiarias de diferentes sabores"},
      {nome:"Frappe", imagem:"cafe15", descr:"Expresso ou Blend de café instantâneo com açucar, água, leite e gelo"},
      {nome:"Iced Coffe", imagem:"cafe16", descr:"Café servido com gelo"},
      {nome:"Indian Filter Coffe", imagem:"cafe17", descr:"Café e chicória produzem um doce café que é servido com leite"},
      {nome:"Kopi Tubruk", imagem:"cafe18", descr:"Um fino café feito com grãos de café fervido e açúcar sólido"},
      {nome:"Long Black", imagem:"cafe19", descr:"Um blend de água quente e expresso"},
      {nome:"Lungo", imagem:"cafe20", descr:"Água quente é passada duas vezes sobre o pó de café para produzir uma forte bebida"},
      {nome:"Melya", imagem:"cafe21", descr:"Blend de cafe com uma colher de cacau e mel"},
      {nome:"Mocha", imagem:"cafe22", descr:"Um cappuccino com a adição de xarope de chocolate"}
    ];
  });
Agora temos uma resposta JSON chamado coffes com todos os 22 tipos de café mais conhecidos do mercado, suas descrições e qual foto corresponde a cada café. E na página principal (arquivo main.html na pasta \app\views) mostramos todos esses tipos, modificando seu código para:
<style type="text/css">
.marketing {
  text-align: center;
  margin: 10px 0 10px 0;
}
.marketing p {
  font-size: 14px;
  margin: 10px 10px 10px 10px;
}
</style>
<div class="jumbotron">
  <h2>Tipos de Cafés Disponíveis</h2>
  <div class="container">
    <div ng-repeat="coffe in coffes">
      <div class="row marketing" ng-show="{{$index%3 == 0}}"></div>
      <div class="col-md-4 col-sm-4 col-xs-12 marketing">
        <img ng-src="images/{{coffe.imagem}}.png" alt="Cafe" class="img-circle">
        <h2>{{coffe.nome}}</h2>
        <p class="marketing">{{coffe.descr}}</p>
        <a href="#/" class="btn btn-default">Detalhes...</a>
      </div>
    </div>
  </div>
</div>
E agora a janela principal possui a seguinte aparência:


E apenas para deixarmos as coisas bem arrumadas. Na classe de teste da janela principal (main.js em /test/spec/controllers/main.js) modifique a seguinte função:
  it('should attach a list of awesomeThings to the scope', function () {
    expect(MainCtrl.awesomeThings.length).toBe(3);
  });
Para:
  it('should attach a list of coffes to the scope', function () {
    expect(scope.coffes.length).toBe(22);
  });
Em breve iremos adicionar mais alguns detalhes para aprendermos como o Yo pode auxiliar na criação dos artefatos necessários e organização de seus projetos, por enquanto recomendo que estude como o projeto está distribuído.

Obrigado e até a próxima
Fernando Anselmo

Um comentário:

  1. Parabéns pelo artigo! Simples e direto. Eu comecei a trabalhar com DHTML em 1999, naquela época ainda havia uma certa incerteza de qual linguagem de script iria reinar, pois a Microsoft estava investindo muito no VBScript, mas eu nunca duvidei da capacidade do Javascript e continuei fiel. Vendo a infinidade de tecnologias que utilizam Javascript hoje em dia me faz orgulhoso de ter feito a escolha certa. Um forte abraço

    ResponderExcluir