AngularJS: Rotas (ngRoute)

E aí galera, beleza?

Hoje falaremos um pouco sobre as rotas (ngRoute) do AngularJS. Nos posts anteriores falamos sobre controladores e serviços, se você ainda não está familiarizado com o framework recomendo a leitura.

Rotas – Para que servem?

Em aplicações que utilizam o conceito de single page, a navegação de uma página para outra é crucial. Quando a aplicação cresce e se torna mais complexa, precisamos encontrar uma maneira de gerenciar as páginas pelas quais o usuário vai navegar através da aplicação.

Poderíamos fazer toda a aplicação em um único arquivo e gerenciar o modo que a tela se comporta fazendo um gerenciamento de estados (por exemplo, escondendo e exibindo componentes), porém, já sabemos que fazer isso é completamente inviável para manutenção e saúde da aplicação (e da nossa querida saúde também!).

O módulo ngRoute é a solução que precisávamos. Ele nos permite gerenciar os templates a serem inseridos na view de acordo com a navegação do usuário. Ou seja, quando há uma ação de mudança de página, o módulo é capaz de “injetar” o template correspondente (desce mais um pouquinho que te mostro como faz).

Como configurar?

O serviço $routeProvider, que faz parte do módulo ngRoute, é utilizado para realizar a configuração das rotas. Ele facilita a conexão do controlador com o template (view) e a URL que será mapeada com a rota. Com esse recurso, podemos utilizar o histórico do navegador e os favoritos.

Nota: $routeProvider é o provider do serviço $route. Por se tratar de um provider, ele só pode ser injetado dentro da função config. Portanto, não podemos utilizar $routeProvider dentro de um controlador.

Instalação

Para utilizar o angular-route em nossa aplicação, precisamos adicionar a referência do javascript após a referência do próprio AngularJS.

<script src="//code.angularjs.org/1.4.4/angular-route.js"></script>

Depois, devemos adicionar a dependência do módulo ngRoute a nossa app.

angular.module('feira-app',['ngRoute'])

Template

Para utilizar um template, é necessário combinar a diretiva ng-view (linha 10) com a rota. Essa diretiva nos permite especificar exatamente onde no DOM nós queremos renderizar o template de acordo com a rota atual.

Por enquanto não vamos nos preocupar com o restante do código, principalmente os que estão entre as linhas 14 e 18, explicarei na sessão de eventos.

A diretiva ngView segue os seguintes passos:

  • Toda vez que o evento $routeChangeSucess é disparado, a view é atualizada;
  • Se houver um template associado com a rota atual, um novo escopo é criado;
  • A última view é removida e, consequentemente, o último escopo é limpo;
  • O novo escopo é vinculado ao novo template;
  • O controlador é vinculado ao escopo, caso haja um controlador para a rota;
  • O evento $viewContentLoaded é disparado.

Configurando as Rotas

A configuração das rotas se dá através dos métodos when otherwise do serviço $routeProvide. Na nossa aplicação, ele está sendo injetado dentro da função config (linha 6).

O método when (linha 7), recebe dois parâmetros (path e route):

O primeiro parâmetro é o path da rota, que é comparado ao $location.path da URL atual. Podemos passar um parâmetro na URL utilizando o ‘:param’, como na nossa rota /animais:id. O resgate desse parâmetro é feito no service $routeparams (linha 18 – index.html).

O segundo parâmetro é o objeto de configuração da rota. É neste momento que definimos qual template e controlador serão injetados. Outras configurações como resolve, redirectTo e reloadOnSearch também são válidas. Os detalhes sobre essas configurações podem ser vistos aqui.

O método otherwise é utilizado para definir uma rota padrão. Assim, quando nenhuma rota for encontrada o AngularJS redirecionará a aplicação para essa rota padrão.

Eventos

O serviço $route dispara eventos em diferentes estágios do fluxo de uma rota. Esses eventos são importantes quando queremos manipular as rotas e são particularmente importantes quando desejamos detectar se um usuário está logado ou não na aplicação.

$routeChangeStart

É disparado antes da mudança da rota. É nesta etapa que todas as dependências necessárias são resolvidas para que a rota mude com sucesso. Uma vez que todas as dependências tenham sido resolvidas o evento $routeChangeSucess é disparado.

Parâmetros:

  • angularEvent: objeto de evento;
  • next: informação sobre a futura rota;
  • current: informação sobre a rota atual;

Aquela explicação que fiquei devendo lá em cima vem agora.

Na função run (linhas 6) estamos setando os services $route, $routeparams e $location no $rootScope. Isso está sendo feito para que possamos utilizar esses serviços na view (linhas 14 a 18 do index.html). Através desses serviços, podemos identificar os parâmetros da URL, qual template e controlador estão sendo injetados na rota atual, entre outras informações.

$routeChangeSuccess

É disparado após a mudança bem sucedida da rota.

Parâmetros:

  • angularEvent: o objeto de evento;
  • current: informação sobre a rota atual;
  • previous: informações da rota anterior, ou undefined se for a primeira rota a ser invocada.

$routeChangeError

Se alguma mudança de rota for rejeitada, esse evento será disparado.

Parâmetros:

  • angularEvent: o objeto de evento;
  • current: informação sobre a rota atual;
  • previous: informações da rota anterior;
  • rejection: a promise que foi rejeitada.

$routeUpdate

Este evento é disparado se a propriedade reloadOnSearch estiver setada com false e se estivermos reutilizando a mesma instância do controlador.

Parâmetros:

  • angularEvent: o objeto de evento;
  • current: informação sobre a rota atual/anterior;

Ainda há configurações que não terei espaço para abordar aqui, como o hashbang mode (html5Mode), o hashPrefix e os detalhes do serviço $location.

Existe um outro módulo de rotas chamado AngularUI Router, que utiliza uma abordagem diferente. Particularmente o considero melhor que o ngRoute. Ele é baseado em estados (states) e não em URL. Falaremos mais sobre ele em um futuro post. 😉

Então é isso pessoal, espero que tenham curtido.

Os arquivos do nosso exemplo podem ser visualizados na íntegra no gist ou no repositório de código do blog. Aqui você pode ver a aplicação rodando.

Tem dúvidas, críticas ou sugestões? Deixe um comentário aí que terei o maior prazer em responder.

Abraços e até a próxima!