• Nenhum resultado encontrado

O framework se adapta e estende o HTML tradicional para uma melhor

expe-riência com conteúdo dinâmico, com a ligação direta e bidirecional dos dados (os

famososdata-binding). Isso permite sincronização automática de models e views,

abstraindo a manipulação do DOM e melhorando os testes.

AngularJS conseguiu atrair muita atenção nesses últimos tempos,

principal-mente devido ao seu sistema inovador de modelagem, facilidade de desenvolvimento

e práticas de engenharia muito sólidas. Alguns dos objetivos do AngularJS são:

1) Abstrair a manipulação do DOM da lógica do app. Isto melhora os testes;

2) Considera os testes do app tão importantes quanto seu desenvolvimento. A

difi-culdade do teste é diretamente afetada pela maneira como o código é estruturado;

3) Abstrai o acoplamento entre o lado cliente e o lado servidor da aplicação.

Permi-tindo que o desenvolvimento do app evolua em ambos os lados, de forma paralela,

e permite o reúso de código.

A versão 1.0 foi lançada apenas em junho de 2012. Na realidade, o trabalho

come-çou em 2009 como um projeto pessoal de Miško Hevery, um funcionário do Google.

A ideia inicial acabou sendo tão boa que, no momento da escrita, o projeto foi

ofi-cialmente apoiado pelo Google, e há toda uma equipe do Google trabalhando em

tempo integral no AngularJS. O projeto é open source e está hospedado no GitHub

(https://github.com/angular/angular.js) . É licenciado pela Google sobre os termos

de licença MIT.

5.2 AngularJS

Para usar a estrutura AngularJS são necessárias duas alterações em nosso documento

HTML, PHP, Rails etc.

A primeira coisa a se fazer é incluir a biblioteca em nosso documento. A segunda,

é incluir a propriedade ng-appno elemento htmlem que queremos “ativar” o

aAgularJS. Neste caso, começamos inserindo na tag <html>do nosso documento.

Veja o exemplo a seguir:

Hello World AngularJS

<html ng-app>

<head>

<title>Titulo Página</title>

<script

src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js">

</script>

</head>

<body>

<input ng-model="nome">

<h1>Olá {{ nome }}</h1>

</body>

</html>

Código online:http://plnkr.co/edit/FemetcT1h1HraRQLnT4x

Mesmo este exemplo simples traz à tona algumas características importantes do

sistema de templates AngularJS:

• Tags HTML personalizados e atributos: são usados para adicionar

comporta-mento dinâmico de um docucomporta-mento HTML de outra forma estática;

• Chaves duplas ({{expressão}}): são utilizadas como um delimitador para

expressões que exibem valores do modelo.

No AngularJS, todas as tags HTML e atributos especiais que o framework

pode compreender e interpretar referem-se comodiretrizes. No exemplo, vimos

a ng-appe a ng-model.

Modelo MVC no AngularJS

Quase todas as aplicações web existentes hoje são baseadas de alguma forma no

padrãomodel-view-controller (MVC). Entretanto, o MVC tem um problema: ele

não é um padrão muito preciso, mesmo possuindo uma boa arquitetura. Para piorar,

existem muitas variações e derivados do padrão original – entre os quais MVP (http:

//pt.wikipedia.org/wiki/Model-view-presenter) e MVVM (http://en.wikipedia.org/

wiki/Model_View_ViewModel) parecem ser os mais populares.

Para aumentar a confusão, há diversas estruturas, e os desenvolvedores tendem

a interpretar os padrões mencionados de forma diferente. Isso resulta em

situa-ções em que o mesmo nome MVC é utilizado para descrever várias arquiteturas e

abordagens de codificação diferentes. Martin Fowler resume isso muito bem em

http://martinfowler.com/eaaDev/.

5.2. AngularJS Casa do Código

O time do AngularJS tem uma abordagem muito pragmática para toda a família

de padrões MVC. Ele declara que o framework é baseado no padrãoMVW

(model-view-whatever). Basicamente é preciso vê-lo em ação para obter a sensação de sua

utilidade:

Visão detalhada

O exemplo que vimos até agora,"Olá Mundo”, não empregou qualquer estratégia

de estratificação explícita: inicialização de dados e lógica.

Em qualquer aplicação no mundo real, no entanto, é preciso prestar mais

aten-ção a um conjunto de responsabilidades atribuídas a cada camada. Felizmente, o

AngularJS oferece diferentes construções arquitetônicas que nos permitem construir

adequadamente aplicações mais complexas.

<!DOCTYPE html>

<html ng-app="nome_meu_app">

<head>

<meta charset="utf-8">

<title>Título Página</title>

<script

src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js">

</script>

<script src="app.js"></script>

</head>

<body>

<div ng-controller="OlaCtrl">

Como você está <input type="text" ng-model="nome"><br>

<h1>Eu estou muito bem, {{nome}}! e você?</h1>

</div>

</body>

</html>

Veja que agora usamos uma nova diretiva, ng-controller, com uma função

JavaScript correspondente. O OlaCtrlaceita um argumento $scope.

var app = angular.module(’nome_meu_app’, []);

app.controller(’OlaCtrl’, function($scope) {

$scope.nome = ’Giovanni’;

});

Código online:http://embed.plnkr.co/82gR2y7Z4mOPwz7gEgSG/preview

Scope

Um $scope, objeto no AngularJS, está aqui para expor o modelo de domínio

para uma visão. Ao atribuir propriedades para uma instância de escopo, podemos

fazer novos valores à disposição de um modelo para renderização.

$scopepode ser ampliado com dados e funcionalidades específicas para um

determinado ponto de vista. Podemos expor lógica específica de UI para os modelos

de definição de funções em uma instância de escopo.

Pode-se criar uma função lerNomepara nossa variável nome.

Exemplo:

var OlaCtrl = function ($scope) {

$scope.lerNome = function() {

return $scope.nome;

};

};

Podemos usá-lo da seguinte maneira:

<h1>Olá, {{ lerNome() }}!</h1>

O objeto $scopenos permite controlar com precisão em qual parte do modelo

as operações estão disponíveis para a camada de visão. Conceitualmente, escopos

AngularJS estão muito perto doViewModel, o padrãoMVVM.

Hierarquias de escopo

Vamos olhar de outra forma para o exemplo simples OlaCtrlque já fizemos:

var OlaCtrl = function ($scope) {

$scope.nome = ’World’;

};

O OlaCtrlé semelhante a uma função regular do construtor JavaScript, não

há absolutamente nada em especial sobre ele além do argumento $scope.

5.2. AngularJS Casa do Código

Um novo $scopefoi criado pela diretiva ng-controllerusando o método

Scope.$New(). Espere um momento, parece que temos de ter pelo menos uma

instância de um escopo para criar um novo escopo. De fato! AngularJS tem uma

notação do $rootScope(um escopo que é pai de todos os outros escopos). A

instância $rootScopeé criada quando uma nova aplicação ébootstrapped

(inicia-lizada).

A diretivang-controlleré um exemplo de uma diretiva de criação de escopo.

AngularJS irá criar uma nova instância da classe Scopesempre que encontrar uma

diretiva de criação de escopo na árvore DOM. Um escopo recém-criado irá apontar

para o seu pai, usando a propriedade $parent.

Vamos dar uma olhada no exemplo que faz uso de uma diretiva ng-repeat:

var MundoCtrl = function ($scope) {

$scope.populacao = 70000000;

$scope.paises = [

{nome: ’Brasil’, populacao: 63.1},

{nome: ’Alemanhã’, populacao: 60.1}

];

};

Nosso HTML fica assim:

<ul ng-controller="MundoCtrl">

<li ng-repeat="pais in paises">

{{pais.nome}} tem uma população de {{pais.populacao}}

</li>

<hr>

População do mundo: {{populacao}} Milhões de pessoas

</ul>

A diretiva ng-repeatnos permite iterar sobre uma coleção de objetos (países)

e criar novos elementos DOM para cada item em uma coleção. A sintaxe da diretiva

deve ser fácil de seguir. Um nova variável paisé criada para cada item e exposta

em um $scope.

Há um problema aqui, ou seja, uma nova variável precisa ser exposta em um

$scopede cada objeto (pais) e não podemos simplesmente substituir valores

an-teriormente expostos. AngularJS resolve este problema através da criação de um

novo escopo para cada elemento de uma coleção.

Views

Nós já vimos exemplos suficientes de modelos AngularJS para perceber que não

é mais uma linguagem de modelagem, mas completamente um monstro. Não só pela

sua sintaxe de modelo e por nos permitir ampliar o vocabulário HTML, mas também

tem a capacidade única de atualizar partes da tela, sem qualquer intervenção manual.

Na realidade, o AngularJS tem até mesmo conexões mais íntimas com o HTML

e o DOM, pois depende de um navegador para analisar o texto do modelo. Depois

que o navegador tansforma o texto da marcação na árvore DOM, o AngularJS

retro-cede e percorre a estrutura DOM analisada. Cada vez que encontrar uma diretiva,

o AngularJS executa sua lógica para transformar diretivas em partes dinâmicas da

tela.

Declarando uma view template

Vamos imaginar que precisamos criar umaLista de Tarefas, cujo propósito é

adi-cionar itens a uma lista, com a opção de marcar como “feito”, e que mostre quantas

tarefas estão prontas. Para isso, precisamos do seguinte template:

<div ng-controller="TarefasCtrl" class="todo">

<span>{{restante()}} de {{todos.length}} restante</span>

<ul class="unstyled">

<li ng-repeat="todo in todos">

<input type="checkbox" ng-model="todo.feito">

5.2. AngularJS Casa do Código

</li>

</ul>

<form ng-submit="addTodo()">

<input type="text" ng-model="todoText" size="30"

placeholder="Adicionar novas tarefas">

<input class="btn" type="submit" value="adicionar">

</form>

</div>

Vamos trabalhar em cima do código anterior. Em primeiro lugar, é preciso

mos-trar quantas tarefas prontas eu tenho em minha lista.

$scope.restante = function() {

var count = 0;

angular.forEach($scope.todos, function(todo) {

count += todo.feito ? 0 : 1;

});

return count;

};

A função restanteé definida pelo controller TarefasCtrl. Veja o exemplo

a seguir:

’use strict’;

var ColetaneaFrontEnd = angular.module(’meu_app’);

ColetaneaFrontEnd.controller(’TarefasCtrl’, function( $scope ) {

$scope.restante = function() {

var count = 0;

angular.forEach($scope.todos, function(todo) {

count += todo.feito ? 0 : 1;

});

return count;

};

});

Agora, é preciso adicionar elementos em nossa lista para que nossa função

restante()funcione. Para isso, vou criar uma lista e depois irei manipulá-la com

a função addTodo()que permite adicionar novos itens.

var app = angular.module(’meu_app’, []);

app.controller(’TarefasCtrl’, function($scope) {

//Lista com as tarefas

$scope.todos = [

{

tarefa:’Tarefa 01’,

feito:true

},

{

tarefa:’Tarefa 02’,

feito:false

},

{

tarefa:’Tarefa 03’,

feito:false

}

];

//Adicionar novos elementos a lista

$scope.addTodo = function() {

$scope.todos.push({ tarefa:$scope.todoText, feito:false });

$scope.todoText = ’’;

};

//Calcular quantas tarefas estão prontas

$scope.restante = function() {

var count = 0;

angular.forEach($scope.todos, function(todo) {

count += todo.done ? 0 : 1;

});

return count;

};

});

Código online:http://embed.plnkr.co/fzc1hHQ08prTgOxKPapD/preview