Single Page Apps com AngularJS
Patrick Augusto Gonçalves
[email protected]
Vamos Começar do Começo
O que são Single Page Apps? Por que usar? O que eu ganho com isso? Modelo Clássico de Aplicações Web
Domain Request Request Request Browser GET /
clientes Network GET /
clientes Controller Servidor HTML Response Response <html> <body> … </body> </html> <html> <body> … </body> </html> View Modelo Clássico – Full Response Cada requisição do browser provoca uma
atualização completa da página.
Além do código HTML, recursos de imagem, scripts
e folhas de estilo também podem ser recarregados,
caso nenhuma medida de cache seja utilizada.
Modelo Clássico – Full Response Tráfego elevado de dados eleva custo de
hospedagem em serviços de cloud computing,
como Amazon EC2 por exemplo.
Apesar de não ser impossível, é mais difícil escalar
uma aplicação no modelo clássico devido
principalmente ao gerenciamento de sessões de
usuários.
Existe uma alternaDva? Sim! Sim! Single Page Apps Single Page Apps Aplicações ou sites web que utilizam apenas
uma página HTML para apresentar os dados
e elementos web, sem precisar recarregar
completamente a página no momento em
que o usuário navega de uma
funcionalidade para outra.
Single Page Apps Primeira requisição carrega o código HTML da
página principal que a partir de então servirá como
visão principal ou “shell” da aplicação.
Códigos JavaScript necessários para a execução da
aplicação também são carregados neste momento.
... assim como folhas de estilo.
Single Page Apps Primeira Requisição GET /
index.html GET /
index.html HTML Browser Próximas Requisições HTML Network HTML Servidor GET /clientes/
1 GET /clientes/
1 Controller GET /clientes/
1 JSON JSON { id: 1, nome: “abc”, fone: 12345 } { id: 1, nome: “abc”, fone: 12345 } index.html { id: 1, nome: “abc”, fone: 12345 } Domain Single Page Apps Primeira Requisição pagina.html Web Browser Servidor Single Page Apps Primeira Requisição GET /pagina.html pagina.html Web Browser Servidor Single Page Apps Primeira Requisição HTTP 200 ok Web Browser pagina.html Servidor Single Page Apps Primeira Requisição pagina.html Web Browser Servidor Single Page Apps Primeira Requisição pagina.html Web Browser Servidor Single Page Apps Primeira Requisição pagina.html Web Browser Servidor Single Page Apps Primeira Requisição pagina.html Web Browser Servidor Single Page Apps Primeira Requisição Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) REST Endpoint Banco de Dados Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) GET /api/users/1 REST Endpoint Banco de Dados Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) GET /api/users/1 REST Endpoint Banco de Dados Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) REST Endpoint Banco de Dados Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) REST Endpoint Banco de Dados Web Browser Servidor Single Page Apps Dados são requisitados através de WebServices (REST na maioria) REST Endpoint HTTP 200 OK application/json { id: 1, username: auser, email: [email protected] } Web Browser Banco de Dados Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. /views/fragment.html Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. GET /views/fragment.html /views/fragment.html Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. HTTP 200 ok text/html /views/fragment.html Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. Web Browser Servidor Single Page Apps Pequenos trechos de código HTML são carregados dinâmicamente. Web Browser Servidor A primeira página não vai ficar
muito pesada?
Técnicas de “minification”, gzip compression e
carregamento dinâmico de scripts (AMD) minimizam
bastante o problema.
Requisições completas no modelo clássico de
aplicações web trafegam uma quantidade
consideravelmente maior de dados durante sua
utilização.
Após a primeira requisição, somente dados e
fragmentos HTML ainda não carregados são obtidos
do servidor.
Primeira Requisição Navegação para Segunda Visão Voltando para Primeira Visão Como eu crio então SPAs com
AngularJS?
Primeiro Passo
Fazer download dos arquivos JavaScript que
devem ser incluídos na aplicação.
www.jquery.org
www.angularjs.org
Primeiro Passo
Primeiro Passo
Primeiro Passo
Segundo Passo
Incluir bibliotecas na página HTML principal da
aplicação através das tag <script>.
<html>
<head>
<title>MyApp</title>
<script type=”text/javascript"
src="/js/jquery-1.11.1.js">
</script>
<script type=”text/javascript"
src="/js/angular.js">
</script>
</head>
<body>
Page Content
</body>
</html>
Terceiro Passo
<codificar/>
Vamos por partes.
AngularJS Building Blocs
Template Engine
Data Binding
Controllers
Services
Routing
Dependency Injection
… entre outros.
Dependency Injection
Considerada por muitos como o ponto mais forte
do AngularJS.
Nos permite injetar dependências em um
controlador, serviço ou diretiva da mesma forma
que frameworks famosos como o Spring, CDI ou
Google Guava fazem na plataforma Java.
Dependency Injection - Exemplo
Definição de dependência. Injeção de dependência. Código disponível em: hZps://github.com/pkgoncalves/ngstore Template Engine
Código HTML comum contendo elementos e
atributos específicos do AngularJS.
AngularJS renderiza as páginas da aplicação,
combinando os elementos de template com os
dados presentes no modelo e nos controladores.
<html ng-app>
<body ng-controller="MyController">
<input ng-model="foo" value="bar”>
<button ng-click="changeFoo()">{{buttonText}}</button>
<script src="angular.js">
</body>
</html>
Template Engine
Algumas das Diretivas Mais Utilizadas
ngInclude: inclui conteúdo HTML em uma página existente.
ngApp: inicializa uma página HTML como um documento de
visão AngularJS.
ngModel: indica a qual propriedade de objeto um campo de
formulário está associado.
ngClick: indica qual método do controller a aplicação deve
executar quando um determinado botão é pressionado.
ngIf: inclui ou exclui um elemento da página HTML.
ngView: indica em qual local o conteúdo das visões da
aplicação devem ser renderizadas (routing engine). Template Engine
No código HTML, as diretivas aparecem no
formato ng-nome-da-diretiva.
Camel case é transformado em palavras
separadas por traços.
ngClick
ngModelOptions
ng-click
ng-model-options
Template Engine
A documentação oficial na página do projeto
contém uma relação de todas as diretivas
disponíveis para utilização em templates.
Template Engine
Template Engine - Exemplo
Repete a tag <tr> para cada elemento da lista “clientes”. Imprime na tag <td> o id de um objeto cliente. Invoca a função excluir do controlador, passando o objeto cliente como parâmetro. Código disponível em: hZps://github.com/pkgoncalves/ngstore A propósito, o que significa
aquele “ng” antes do nome de
cada diretiva?
ng = Angular
Prefixo reservado. Utilizado para identificar as
diretivas implementadas pelo próprio AngularJS.
Sim, você pode criar suas próprias diretivas.
Mais informações em:
https://docs.angularjs.org/guide/directive
Um template sozinho não faz
verão.
Por isso, apresentamos os
Controladores.
Por isso, apresentamos os
Controladores.
Ligue agora para 0800 999 8817902 3 para *adquirir o seu.
*
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam erat eros, pretium ac fringilla id, ullamcorper eu purus. Cras pellentesque, nunc sed hendrerit convallis, est urna malesuada sem, sit amet aliquet est
dolor sed diam. Sed lacinia elementum risus a euismod. Sed condimentum eros eget nisi sodales, eget luctus orci convallis. Aliquam erat volutpat.
Controladores
No AngularJS, controladores são utilizados para
se programar o comportamento das visões.
Controladores sempre estão associados a um
escopo.
Controladores
Utilize controladores para:
Configurar o estado inicial do escopo de uma visão.
Adicionar comportamento ao escopo de uma visão.
Controlador - Exemplo
Nome do módulo ao qual o controlador será adicionado. Injeção do objeto escopo. Este objeto será também uDlizado pelo template para renderização da página. Nome do controlador. Inicialização de variáveis. Código disponível em: hZps://github.com/pkgoncalves/ngstore Roteamento
AngularJS possui um mecanismo de roteamento
pronto para uso.
Deve ser inicializado no momento da configuração
inicial de um módulo.
Trabalha em conjunto com a diretiva ngView, pois
é na área definida por ela que a nova visão será
renderizada.
Roteamento - Exemplo
Definição do módulo. Função de configuração. Devemos declarar a dependência do módulo ngRoute e injetar o objeto $routeProvider. Definição de rota. Rota padrão. Executada quando o caminho da URL da aplicação não combina com nenhuma das opções definidas pela função when. Código disponível em: hZps://github.com/pkgoncalves/ngstore Roteamento - Exemplo
Rota /clientes Roteamento - Exemplo
Rota /clientes/adicionar
Roteamento
Também é possível definir variáveis em uma rota.
Variável “id” . Roteamento
Variável “id” . Roteamento
Para recuperar o valor de uma variável de roteamento
no código do controlador utilize o objeto
$routeParams.
Variável “id” . Injeção de dependência do objeto $routeParams. Roteamento
Para usar o mecanismo de roteamento, o
arquivo angular-route.js deve ser
adicionado ao projeto.
Roteamento
www.angularjs.org
Roteamento
www.angularjs.org
Roteamento
www.angularjs.org
Roteamento
www.angularjs.org
Roteamento
Finalmente, importar o arquivo angular-route.js na página
principal da aplicação.
Services
São objetos JavaScript que podem ser injetados em
controladores ou outros services através do
mecanismo de injeção de dependência do
AngularJS.
Bastante utilizado na organização e reutilização de
código em aplicações AngularJS.
Utilize o método factory() ou o serviço $provide para registrar seus objetos de serviço.
Service - Exemplo
Seleção do módulo ao qual o serviço pertencerá. Nome do serviço. Injeção de dependência. Métodos do serviço. Código disponível em: hZps://github.com/pkgoncalves/ngstore Service
AngularJS possui muitos serviços prontos para uso. Consulte a
relação completa em:
https://docs.angularjs.org/api/ng/service Como eu junto tudo isso em uma
aplicação então?
Aplicação de Exemplo
Aplicação de Exemplo
Utiliza Node.js como tecnologia Server Side.
Node.js implementa as APIs REST e fornece a
página principal da aplicação (shell) e demais
elementos, como imagens, arquivos de script, CSS
e etc.
Aplicação de Exemplo
Web Browser Servidor Banco de Dados Utilize qualquer plataforma server
side para implementar
WebServices e fornecer os
elementos da sua aplicação.
Estrutura de Pastas
Estrutura de Pastas
Existem várias formas de se estruturar o código em
uma aplicação AngularJS.
Podemos escrever todos os controladores, serviços e
configurações em um único arquivo.
Podemos criar um único arquivo para armazenar todos
os controladores, outro para os serviços e assim por
diante.
Podemos separar os arquivos da aplicações em
estruturas lógicas, uma pasta para controladores, outra
para serviços, outra para visões e etc.
Estrutura de Pastas
Existem várias formas de se estruturar o código em
uma aplicação AngularJS.
Podemos escrever todos os controladores, serviços e
configurações e um único arquivo.
Podemos criar um único arquivo para armazenar todos
os controladores, outro para os serviços e assim por
diante.
Podemos separar os arquivos da aplicações em
estruturas lógicas, uma pasta para controladores, outra
para serviços, outra para visões e etc.
Estrutura de Pastas
Existem várias formas de se estruturar o código em
uma aplicação AngularJS.
Podemos escrever todos os controladores, serviços e
configurações e um único arquivo.
Podemos criar um único arquivo para armazenar todos
os controladores, outro para os serviços e assim por
diante.
Podemos separar os arquivos da aplicações em
estruturas lógicas, uma pasta para controladores, outra
para serviços, outra para visões e etc.
Estrutura de Pastas
Existem várias formas de se estruturar o código em
uma aplicação AngularJS.
Podemos escrever todos os controladores, serviços e
configurações e um único arquivo.
Podemos criar um único arquivo para armazenar todos
os controladores, outro para os serviços e assim por
diante.
Podemos separar os arquivos da aplicações em
estruturas lógicas, uma pasta para controladores, outra
para serviços, outra para visões e etc.
Estrutura de Pastas – Projeto Completo
Models Node.js Pastas com recursos JavaScript, CSS e fragmentos HTML. Aplicação AngularJS. Definição de rotas Node.js. Página principal da aplicação. Estrutura de Pastas – Detalhamento
Controladores AngularJS. Definição do módulo principal. Definição de serviços. Fragmentos HTML (visões). Tudo começa pela página index.
/views/index.ejs Adicione as bibliotecas do
AngularJS e demais
dependências.
/views/index.ejs A inclusão da biblioteca JQuery não é obrigatória. Quando ela não é
adicionada, o AngularJS utiliza uma versão embutida e simplificada do
JQuery.
Inclua a diretiva ngApp na tag
principal da página. Pode ser até
mesmo a própria tag <html>.
/views/index.ejs O conteúdo da diretiva ng-app é de livre escolha e deve representar o
nome do módulo principal da aplicação.
Crie o arquivo JavaScript que irá
inicializar o módulo principal da
sua aplicação.
/public/ngstore-­‐app.js Inclua o arquivo de definição do
módulo principal da aplicação na
página index.html.
/views/index.ejs As tags <script> responsáveis pelo carregamento dos controladores,
serviços e demais elementos da sua aplicação, devem de preferência ser
incluídos no rodapé da página. Assim o usuário terá a interface completa
renderizada no browser enquanto os demais scripts são carregados.
Agora utilize a diretiva ngView para
definir em qual região da página
index.html as demais visões serão
renderizadas quando o usuário
navegar de uma página para outra.
/views/index.ejs Visão de Cadastro de Clientes
3 elementos:
Fragmento HTML de template;
Controlador;
Definição de roteamento (url da visão).
Arquivo de template HTML deve ser
criado na pasta dedicada ao
armazenamento de visões na
aplicação.
/public/app/views/cliente-­‐edit.html Repare na diretiva ng-­‐model no
elemento <input>. Ela faz a ligação (data binding) entre um objeto no
controlador e os elementos de um formulário. Alterações
no formulário alteram o modelo e vice-versa,
automaticamente. Após implementado o template,
devemos criar o controlador
responsável pelos dados e ações da
página.
/public/app/controllers/ClienteEditController.js Alguns métodos de ações do controlador
estão ligados ao template através da diretiva
ng-click.
Importe o arquivo JavaScript do controlador
na página principal da aplicação.
Devemos agora criar um roteamento
para permitir que o usuário navegue
para o formulário de cadastro de
clientes. O roteamento também define
qual controlador estará relacionado ao
template da visão.
/public/app/ngstore-­‐app.js Não se esqueça de injetar o serviço routeProvider. Necessário para definir os roteamentos. Arquivo de template. Controlador. O roteamento deve ser definido na configuração do
módulo principal da aplicação ou de um submódulo da
aplicação.
A navegação para a visão de cadastro
de clientes pode ser feita através do
elemento <a> do HTML.
<a href=“#/clientes/adicionar”>Novo Cliente</a> O símbolo # é necessário antes do caminho da rota,
caso contrário, o navegador irá buscar uma página
completa no caminho /clientes/adicionar.
É possível utilizar rotas sem o uso de
hashbangs. Para isso utilize o serviço
$locationProvider, passando o valor true
para o método html5Mode. angular.module('storeapp’, [’locationProvider’]) .config(['$locationProvider', function ($routeProvider) { $locationProvider.html5Mode(true); }]); Código da Aplicação de Exemplo
Disponível no GitHub em:
https://github.com/pkgoncalves/ngstore
Patrick Augusto Gonçalves
[email protected]
Obrigado!
Download

da palestra