Neste artigo vou mostrar como criar uma aplicação ASP .NET Single Page Application usando os recursos do AngularJS com Web API: definindo o routing.
Na terceira parte do artigo, criamos a nossa aplicação Angular definindo o module, o controller e usando o serviço $http para obter informações do nosso banco de dados, exibindo-os na view Index.cshtml.
Um recurso muito poderoso do angular é o roteamento de páginas. O módulo ngRoute do Angular fornece serviços para realizar o roteamento de páginas para alguma rota pré-definida. Este recurso está disponível como um arquivo chamado angular-route.js, separado do pacote angular.js.
Para usar o recurso, basta referenciar o arquivo angular-route.js e registrar o ngRoute no módulo da aplicação Angular.
Nota: Você pode baixar o arquivo angular-route.js neste link (podemos instalar o pacote via Nuget).
angular.module(“nomeModulo”,[“ngRoute”]);
Depois, basta configurar a rota específica usando o serviço $routeProvider e uma rota padrão, caso nenhuma rota seja encontrada.
O serviço $routeProvider possui dois métodos para fazer isso:
-
when(path, rota) – define uma rota específica
-
otherwise(path) – define rota padrão
O método when recebe dois parâmetros (path e route):
- O primeiro parâmetro é o path da rota
- O segundo parâmetro é o objeto de configuração da rota. É neste momento que definimos qual template e controlador serão injetados.
O método otherwise é utilizado para definir uma rota padrão.
Quando nenhuma rota for encontrada, o AngularJS redirecionará a aplicação para essa rota padrão.
Exemplo:
$routeProvider .when('/', { templateUrl: '/views/home.html' }) .when('/artigos', { templateUrl: 'views/artigos.html', controller: 'ArtigosController'}) .when('/sobre', { templateUrl: 'views/sobre.html', controller: 'SobreController'}) .otherwise({redirectTo: "/"})
Após isso, para exibir o resultado da renderização das páginas, basta usar a diretiva ng-view na página principal (master page).
<div ng-view> </div>
A figura abaixo mostra um esquema de funcionamento do roteamento no AngularJS:
Para navegar entre as rotas podemos usar links : <a href=”#/produtos”>Produtos</a>
Para redirecionar ou retornar para uma determinada rota, podemos usar:
- redirectTo : “/produtos”
- $location.path(“/produtos”)
Onde o serviço $location analisa a URL na barra de endereços do navegador (baseado em window.location) e torna essa URL disponível para a sua aplicação. Alterações na URL na barra de endereços são refletidas no serviço $location e essas mudanças são refletidas na barra de endereços do navegador. ( https://docs.angularjs.org/guide/$location)
Recursos usados:
- Visual Studio 2015 Community
- AngularJS
- Web API
- Entity Framework
Nota: Baixe e use a versão Community 2015 do VS. Ela é grátis e é equivalente a versão Professional.
Definindo o roteamento na aplicação Angular
Abra a solução Filmoteca criada no artigo anterior no VS Community 2015 (Open Project). No menu Tools-> Nuget Package Manager, clique em Manage Nuget Packages for Solution. Depois informe o nome angular route e selecione o pacote AngularJS.Route, selecionando o projeto e clicando no botão Install:
O pacote javascript angular-route.js será instalado na pasta Scripts do projeto.
Agora temos que incluir a referência a esse pacote em nosso arquivo Index.cshtml na seção scripts:
... @section scripts { <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script> <script src="~/AngularApp/js/filmoteca.js"></script> <script src="~/AngularApp/js/listaController.js"></script> }
Vamos também incluir uma dependência ao roteamento em nosso módulo Angular, incluindo no arquivo filmoteca.js da pasta js o código conforme mostrado abaixo:
(function () { var app = angular.module('filmoteca', ["ngRoute"]); }());
Lembre-se que as dependências são informadas como o segundo parâmetro para o método module; onde o parâmetro é um array de strings contendo os nomes dos módulos requeridos.
Para o roteamento o nome é ngRoute.
Agora estamos prontos para definir o roteamento em nossa aplicação Angular usando um método config e o serviço $routeprovider, onde$routeProvider é o provider do serviço $route.
Por se tratar de um provider, ele só pode ser injetado dentro da função config (não podemos utilizar $routeProvider dentro de um controlador).
Abra o arquivo filmoteca.js e inclua o código abaixo neste arquivo:
(function () { var app = angular.module("filmoteca", ["ngRoute"]); var config = function ($routeProvider) { $routeProvider .when("/", { templateUrl: "/cliente/html/lista.html", controller: "listaController" }) .when("/detalhes/:id", { templateUrl: "/cliente/html/detalhes.html", controller: "detalhesController" }) .otherwise( { redirecTo: "/"}); }; app.config(config); }());
No código acima definimos duas rotas:
- para a raiz do projeto (“/”) a rota é : /cliente/html/lista.html
- para a url /detalhes/id a rota é : /cliente/html/detalhes.html
Onde estamos acessando os arquivos lista.html e detalhes.html na pasta html dentro da pasta cliente. Vamos, agora, criar a pasta Cliente e dentro dela uma outra pasta html; a seguir, criaremos os arquivos html lista.html e detalhes.html.
Criando os arquivos HTML do roteamento na pasta html e o controller detalhesController
Selecione o projeto e no menu Project clique em New Folder e informe o nome Cliente. A seguir, clique com o botão direito sobre a pasta Cliente e no menu Project clique em New Folder e informe html. Agora clique com o botão direito do mouse sobre a pasta html e a seguir em Add -> New Item. Em seguida selecione o template HTML page e informe o nome lista.html. Inclua o código abaixo neste arquivo:
<div ng-app="filmoteca" ng-controller="listaController"> <table class="table"> <tr> <th>Título</th> </tr> <tr ng-repeat="filme in filmes"> <td>{{filme.Titulo}}</td> <td> <a href="#/html/detalhes/{{filme.Id}}">Detalhes</a> </td> </tr> </table> </div>
O código acima usa uma tabela HTML e a diretiva ng-repeat para percorrer o array de filmes que será obtido do banco de dados via WebApi.
A seguir, definimos um link usando a rota detalhes/id de forma que quando o usuário clicar no link será montada a URL: detalhes/id onde id é o código do filme que será passado como um parâmetro.
Repita o procedimento e crie o arquivo detalhes.html com o código a seguir na mesma pasta:
<div ng-controller="detalhesController"> <h2> Filme : {{filme.Titulo}} </h2> <div> <h3> Lançamento em : {{filme.AnoLancamento}} </h3> </div> <div> <h3>{{filme.Duracao}} minutos de duração.</h3> </div> <hr /> <a href="#/">Lista</a> </div>
Perceba que o controller usado na página html é o controle detalhesController que teremos que definir na pasta js.
Clique, então, com o botão direito do mouse sobre a pasta js e a seguir em Add-> New Item.
Selecione o template JavaScript file e informe o nome detalhesController.js, incluindo, a seguir, o código abaixo neste arquivo:
(function (app) { var detalhesController = function ($scope, $http, $routeParams) { var id = $routeParams.id; $http.get("/api/filme/" + id) .success(function (data) { $scope.filme = data; }); }; app.controller("detalhesController", detalhesController) }(angular.module("filmoteca")));
Este controlador utiliza dois serviços: o serviço $routeParams e o serviço $http.
O serviço $routeParams contém os parâmetros adquiridos a partir da URL, como o valor para o Id do filme. Obtendo o Id e combinando-o com a URL, permite-se que o serviço $http retorne os detalhes atualizados para o filme específico e coloque os dados no objeto $scope para posterior apresentação na view.
Vamos ajustar agora a view Index.cshtml na pasta Views/Home substituindo o código existente pelo código abaixo:
<div class="well"> <h4>Macoratti .net</h4> </div> <div data-ng-app="filmoteca"> <ng-view></ng-view> </div> @section scripts { <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script> <script src="~/AngularApp/js/filmoteca.js"></script> <script src="~/AngularApp/js/listaController.js"></script> <script src="~/AngularApp/js/detalhesController.js"></script> }
No código acima incluímos a diretiva ng-view para renderizar as páginas html definidas no roteamento e a referência ao controllerdetalhesController.js criado.
Executando o projeto, iremos obter o seguinte resultado:
Note que o link Detalhes monta a url : #/detalhes/id. Clicando em qualquer um dos links iremos obter os detalhes do filme especificado pelo id:
Poderíamos implementar aqui a edição dos dados, mas antes de prosseguir com essa tarefa vamos incrementar o nosso projeto acrescentando uma abstração ao serviço $http para tornar a interação com a Web API mais fácil.
Na próxima parte do artigo vamos criar um serviço customizado para encapsular os recursos da Web API FilmeController de forma a não termos que usar o serviço $http diretamente dos controllers.
Pegue o projeto até esta etapa aqui: Filmoteca4.zip (sem as referências)