Imagem post: Criando uma aplicação simples com AngularJS
Javascript

Criando uma aplicação simples com AngularJS

Com a missão de enriquecer o vocabulário HTML o framework AngularJS chega com a marca Google de simplicidade e promete um workflow diferente para os desenvolvedores.

Por
22

AngularJS é o mais novo lançamento do time de desenvolvedores do Google. Diferentemente de outros frameworks JavaScript, ele adota uma abordagem mais ligada à sintaxe HTML, funcionando como uma espécie de extensão da linguagem.

Neste artigo, vamos criar uma aplicação simples de lista de compras e aprender os conceitos básicos do framework no que diz respeito à associação, manipulação e exibição de dados.

Estrutura inicial

Assim como qualquer aplicação web, nosso ponta-pé inicial acontece com a criação de um página básica. A diferença aqui é que vamos informar um nova propriedade na tag do nosso arquivo: ng-app.

<html ng-app>
    <head>
        <title>Lista de compras</title>
        <script src="http://code.angularjs.org/1.0.1/angular-1.0.1.min.js"></script>
    </head>
    <body>
    </body>
</html>

Essa é a grande sacada do AngularJS. Ao declarar a propriedade ng-app, estamos inicializando a nossa aplicação. É a primeira de algumas novas propriedades que iremos utilizar. Todo o funcionamento do framework gira em torno dessas novas declarações.

O atributo ng-app na tag informa que o nosso DOM, além de HTML, é também um documento AngularJS. Esta propriedade pode ser utilizada em qualquer elemento do DOM — em alguns casos, apenas uma parte do seu HTML será uma aplicação Angular. Por baixo dos panos, o framework define o elemento com o atributo ng-app como a raiz da aplicação.

Olá, Tableless!

Para provar que o foco do Angular está no HTML e não no JavaScript, vamos implementar um exemplo simples em nossa estrutura:

<html ng-app>
    <head>
        <title>AngularJS - Tableless</title>
        <script src="http://code.angularjs.org/1.0.1/angular-1.0.1.min.js"></script>
    </head>
    <body>
        <input type="text" ng-model="nome">
        <p>Olá, Tableless! Meu nome é: {{ nome }}</p>
    </body>
</html>

Ao carregarmos esse HTML no navegador e digitarmos qualquer coisa no input, o parágrafo é atualizado automagicamente. Perceberam que até agora não escrevemos nenhum código JavaScript?

A propriedade ng-model funciona como um canal entre a nossa view e o form. Ela pode ser utilizada em inputs do tipo texto, selects, textareas, checkboxes e radio buttons.

O model, seus dados e suas validações ficam automaticamente disponíveis no escopo da nossa aplicação, como veremos a seguir.

A associação de dados é feita através do famoso “bigode-bigode” ({{ }}), passando nomes presentes no escopo (no exemplo acima, o model nome).

Enfim, JavaScript!

Chegou a hora de escrevermos nosso primeiro trecho de código JavaScript. Vamos criar um controller para nossa aplicação que carrega uma lista inicial de ítens. Os ítens são armazenados no escopo da aplicação ($scope).

function ListaComprasController($scope) {
    $scope.itens = [
        {produto: 'Leite', quantidade: 2, comprado: false},
        {produto: 'Cerveja', quantidade: 12, comprado: false}
    ];
}

E é só isso por enquanto!

Exibindo nossos ítens

Vamos agora adicionar um novo bloco HTML com a tabela de listagem dos produtos:

<div ng-controller="ListaComprasController">
    <table>
      <thead>
        <tr>
          <th>Produto</th>
          <th>Quantidade</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="item in itens">
          <td><strong>{{ item.produto }}</strong></td>
          <td>{{ item.quantidade }}</td>
        </tr>
      </tbody>
    </table>
</div>

Duas novidades foram apresentadas no HTML acima:

  • o atributo ng-controller informa o nome do controller JavaScript responsável pelo bloco contido no elemento, no nosso caso o controller ListaComprasController definido anteriormente.
  • o atributo ng-repeat executa um loop na variável itens declarada no escopo da aplicação, retornando cada ítem e imprimindo o produto e a quantidade em uma linha da nossa tabela. O formato é: <retorno> in <coleção>.

Adicionando produtos

Para não ficarmos apenas com 4 linhas de JavaScript, vamos adicionar uma funcionalidade que inclui ítens em nossa lista de compras.

O primeiro passo é criar um formulário que será responsável pela ação:

<form class="form-inline" name="formItem">
  <input type="text" ng-model="item.produto">
  <input type="number" ng-model="item.quantidade">
  <button ng-click="adicionaItem()">adicionar ítem</button>
</form>

Estamos utilizando de novo o atributo ng-model para definir um model para os nossos inputs. O controller passa a receber diretamente informações sobre esses campos.

A novidade dessa vez fica por conta do atributo ng-click, que recebe uma função que precisamos declarar no controller:

function ListaComprasController($scope) {
    $scope.itens = [
        {produto: 'Leite', quantidade: 2, comprado: false},
        {produto: 'Cerveja', quantidade: 12, comprado: false}
    ];

    $scope.adicionaItem = function () {
        $scope.itens.push({produto: $scope.item.produto,
                           quantidade: $scope.item.quantidade,
                           comprado: false});
        $scope.item.produto = $scope.item.quantidade = '';
    };
}

Ao clicarmos no botão, o produto é adicionado à tabela. Aqui o model poderia estar realizando diversas validações disponíveis na API do framework entre outras coisas. Porém, no nosso exemplo, apenas adicionamos um novo ítem à lista de produtos e em seguida limpamos os models (os campos do formulário).

Testes

Por ser um framework que demanda um código JavaScript mais estruturado, fica bem simples testar sua aplicação. Utilizando Jasmine, por exemplo, poderíamos facilmente testar o controller dessa forma:

describe('Lista Compras Unitário', function () {
    describe('ListaComprasController', function () {
        beforeEach(function () {
            this.$scope = {};
            this.controller = new ListaComprasController(this.$scope);
        });

        it('deve criar "itens" com 2 ítens', function () {
            expect(this.$scope.itens.length).toBe(2);
        });

        describe('adicionaItem', function () {
            it('deve adicionar um novo ítem à lista com dados do escopo', function () {
                this.$scope.item = {};
                this.$scope.item.produto = 'Carne';
                this.$scope.item.quantidade = 5;
                this.$scope.adicionaItem();
                expect(this.$scope.itens.length).toBe(3);
                expect(this.$scope.itens[2].produto).toBe('Carne');
                expect(this.$scope.itens[2].quantidade).toBe(5);
                expect(this.$scope.itens[2].comprado).toBeFalse;
            });
        });
    });
});

AngularJS é muito mais do que isso!

Deixei muitos tópicos de fora por enquanto. O objetivo aqui era mostrar o potencial do framework AngularJS. Seus recursos ainda incluem rotas, múltiplas views, AJAX e serviços REST e a criação de componentes personalizados. O que vocês viram foi o básico do básico, uma introdução.

No site do framework há uma documentação bem completa, com diversos tutoriais.

O código fonte do nosso exemplo vocês encontram no Github do Tableless. E nesse link vocês conseguem visualizar nossa lista de compras em ação.

Finalizando, nosso camarada Vedovelli gravou um screencast bem completo sobre o AngularJS, recomendo!


  • Bruno Almeida

    Muito massa esse artigo! Já vou testar agora, e pelo visto, essa nova tecnologia vai ser um sucesso!

    Parabéns pelo post! Nota 10

  • http://treinosmart.com/ Caio Ribeiro Pereira

    Automagicamente?? Essa foi boa!!! Muiito show esse AngularJS vou fazer um teste drive pra ver se reduz alguns código JQuery e JS nativo na minha app.

  • Douglas Delabrida

    Muito bom. 

  • Chander Valle

    Não conhecia, a primeira vista ele lembra muito o knockoutjs, achei ele um pouco intrusivo. Conhece o backbonejs ? vale apena da uma olhada nele .. até ….

  • Deivid Marques

    Muito interessante esse framework, valeu por compartilhar conosco! Ele é mais indicado para aplicacoes mobile?

  • João Batista Ferreira

    Isso pode vir a ser um concorrente das bibliotecas ou podemos considerar que fazem trabalhos paralelos?

  • http://twitter.com/jetompson Cesimar Xavier

    Sem dúvida que será um sucesso.. Já vou começar a estudá-la e colocar no meus projetinhos..

    Sobre o artigo, muito bom. Parabéns Davi, sempre trazendo novidades boas ai.

  • http://twitter.com/davitferreira Davi Ferreira

    Fala João! Trabalhos paralelos, com certeza! É apenas uma separação da lógica.

  • http://tutsmais.com.br/blog/ @felquis

    Achei muito bom, bom de mais.. e tenho algumas perguntas:
     1 – Como iremos validar nossos documentos HTML com esses atributos? Eles não podem usar o data-* para os documentos serem validados?
     3 – Leitores de tela conseguem ver esses conteúdos?
     4 – Ele é recomendado para aplicações, então quando o assunto é o conteúdo ser indexado por um robô ou algo assim, ele não é indicado?

  • João Batista Ferreira

    Boas perguntas, e acho que a discussão aqui é o verdadeiro propósito do framework. Com certeza estamos falando de aplicações com funcionalidades específicas e público específico. Além disso, dá pra fazer um site acessível, basta definir corretamente onde e como as funcionalidades devem ser usadas.

  • http://blog.focusteam.com.br Alex Figueiredo

    Só pra complementar:

    1 – Você pode utilizar data-ng-model, data-ng-whatever, e tornar assim seu documento válido.2 – Se ele executar Javascript, sim.
    3 – Existem algumas discussões à respeito no grupo deles. Da uma pesquisada por SEO.

  • http://twitter.com/JohnyLab Jo

    Eu rascunhei um aplicativo de urna eletrônica pra experimentar. Não explorei quase nada do framework, mas só o básico já é impressionante. http://jsfiddle.net/johnylab/Rwk3X/embedded/result/

  • MaxMax

    É bem interessante. Quando teremos mais exemplos?

  • Weuller Krysthian

    Queria fazer um repeat em uma estrutura como se fosse um array, teria como? com varios niveis, tipo:

    $scope.itens = [
        {
            produto: {
                nome: ‘nome do produto’,
                valor: ‘valor do produto’
            },
            categoria: {
                id: ‘id da categoria’,
                nome: ‘nome da categoria’
            }       
        },
        {
            produto: {
                nome: ‘nome do produto’,
                valor: ‘valor do produto’
            },
            categoria: {
                id: ‘id da categoria’,
                nome: ‘nome da categoria’
            }       
        }

  • Weuller Krysthian

     Consegui galera, dei uma viajada aki, só montar a estrutura certim, e dar um ng-repeat dentro do outro….

  • http://www.facebook.com/profile.php?id=1389544587 Fabio Vedovelli

    Obrigado pela menção ao screencast! Eu venho usando o AngularJS em dois projetos reais e já não me vejo sem ele!

  • http://twitter.com/JohnyLab Johnylab.net

    Eu gostaria de ver mais vídeos seus. Os que tem no Youtube são muito cansativos e complicados.

  • MaxMax

    Realmente falta material “nacional” sobre o assunto.

  • Pikock

    Bootstrap Magic made with AngularJS.Create simply your own Twitter Bootstrap theme. E bacana !

    http://pikock.github.com/bootstrap-magic/

  • Ramon Victor

    Parabéns pelo artigo, Davi!
    Esse Angular é realmente mágico! :)

  • Pingback: 3 ferramentas para criar e gerenciar projetos web - Tableless

  • http://www.facebook.com/people/Lucas-Almeida/100002025535898 Lucas Almeida

    Rapaz, estou começando a conhecer o angular e realmente é magico
    Desenvolvo em php e sempre reclamei da falta de dinamismo da linguagem
    Agora animei de começar a fazer meus projetos com angular

Mais artigos