.NET

30 mai, 2016

ASP .NET – Single Page Application (SPA) usando AngularJS com Web API – Parte 05

Publicidade

Neste artigo, eu vou mostrar como criar uma aplicação ASP .NET Single Page Application usando os recursos do AngularJS com Web API: Criando um serviço.

Na quarta parte do artigo, definimos o roteamento em nossa aplicação Angular, criamos o controller detalhesController e agora estamos navegando para a página que exibe os filmes e também os detalhes de um filme.

Neste artigo, vamos criar um serviço customizado de forma a encapsular a lógica de acesso às informações dos filmes em um service do Angular.

Os services do AngularJS são objetos substituíveis que estão ligados entre si usando a injeção de dependência (DI). Você pode usar serviços do Angular para organizar e compartilhar código (reuso) em seu aplicativo.

Os serviços do Angular são:

  1. Instanciados tardiamente (Lazy Load) – O Angular somente instancia um serviço quando um componente da aplicação depende disso.
  2. Singletons – Cada componente dependente de um serviço obtém uma referência a uma única instância gerada pela fábrica de serviço.

O Angular oferece vários serviços úteis (como $http, $log, $route, $location, $window etc.), mas podemos criar serviços de acordo com a necessidade da nossa aplicação.

Para usar um serviço Angular, basta adicioná-lo como uma dependência para o componente (controlador, serviço, filtro ou diretiva) que depende do serviço. O subsistema de injeção de dependência do Angular cuida do resto.

Vamos, então, criar um serviço customizado para a nossa aplicação que encapsula as capacidades da Web API FilmeController, de forma que nossos controladores não precisem usar o serviço $http diretamente.

Existem três maneiras principais de criar registros e serviços:

  1. Service: Quando você estiver usando um Service, ele é instanciado com a palavra-chave “new”. Por causa disso, você vai adicionar propriedades a “this” e o serviço retornará “this”. Quando você passar o serviço ao seu controlador, essas propriedades em “this” estarão disponíveis no controlador por meio de seu serviço.
  2. Factory (a forma mais popular de criar services):  Ao usar um Factory, você cria um objeto, adiciona propriedades a ele e então retorna o mesmo objeto. Quando você passar esse serviço ao seu controlador, as propriedades do objeto estarão disponíveis no controlador por meio de sua factory.
  3. Provider: Os provedores são o único serviço que você pode passar para a função config(). Use um Provider quando você desejar fornecer configuração ao módulo para o objeto de serviço antes de torná-lo disponível.

Recursos usados:

Nota: Baixe e use a versão Community 2015 do VS; ela é grátis e é equivalente à versão Professional.

Criando um serviço AngularJS

Abra a solução Filmoteca criada no artigo anterior no VS Community 2015 (Open Project).

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 filmeService.js.

Defina o código abaixo nesse arquivo:

(function (app) {    

    var filmeService = function ($http, filmeApiUrl) {

        var getFilmes = function() {
            return $http.get(filmeApiUrl);
        };

        var getFilmePorId = function (id) {
            return $http.get(filmeApiUrl + id);
        };

        var atualizar = function (filme) {
            return $http.put(filmeApiUrl + filme.Id, filme);
        };

        var criar = function (filme) {
            return $http.post(filmeApiUrl, filme);
        };

        var deletar = function (filme) {
            return $http.delete(filmeApiUrl + filme.Id);
        };

        return {
            getFilmes: getFilmes,
            getFilmePorId: getFilmePorId,
            atualizar: atualizar,
            criar: criar,
            deletar: deletar
        };
    };

    app.factory("filmeService", filmeService);

}(angular.module("filmoteca")))

No arquivo filmeService.js, criamos um serviço e estamos encapsulando os recursos da Web API FilmeController, de forma que agora o nossos controllers AngularJS não vão precisar usar o serviço $http diretamente.

Observe que o serviço está imitando a API FilmeController do lado do servidor fornecendo métodos para retornar todos os filmes, obter um filme pelo seu Id, atualizar, criar e deletar um filme. Cada um desses métodos encaminha uma chamada para o serviço $http, o qual é uma dependência de filmeService.

Note que em filmeService temos também uma dependência de filmeApiUrl, o que demonstra como passar a informação da configuração de uma aplicação para os serviços e outro componente dentro da aplicação pelo registro de valores constantes durante a configuração da aplicação.

Voltemos então para o arquivo filmoteca.js, no qual as rotas estão definidas e vamos registrar o valor constante usando o método constant. Esses valores usam uma chave como primeiro parâmetro e o valor associado com a chave como segundo parâmetro. Nosso arquivo filmoteca.js deve ficar com o seguinte código:

(function () {

    var app = angular.module("filmoteca", ["ngRoute"]);

    var config = function ($routeProvider) {

        $routeProvider
        .when("/",
               { templateUrl: "/cliente/html/lista.html"})
        .when("/detalhes/:id",
               { templateUrl: "/cliente/html/detalhes.html"})
        .otherwise(
               { redirecTo: "/"});
    };
    app.config(config);
    //inclusão
    app.constant("filmeApiUrl", "/api/filme/");
}());

Qualquer componente que precisar chamar FilmeController pode agora requisitar a dependência filmeApiUrl, mas somente filmeService vai precisar desse valor. Para usar o serviço, vamos incluir o script na view Index.html:

<div class="well">
    <h4>Macoratti .net</h4>
</div>

<div 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>
    <script src="~/AngularApp/js/filmeService.js"></script>
}

Podemos agora alterar o controller listaController para usar o serviço criado em vez de usar o $http:

(function (app) {

    var listaController = function ($scope, filmeService)
    {
        filmeService
            .getFilmes()
            .success(function (data) {
            $scope.filmes = data;
            });
    };

    app.controller("listaController", listaController)

}(angular.module("filmoteca")));

Vamos fazer a mesma coisa com o controller detalhesController:

(function (app) {

    var detalhesController = function ($scope, $routeParams, filmeService)
    {
        var id = $routeParams.id;
        filmeService
            .getFilmePorId(id)
            .success(function (data) {
            $scope.filme = data;
        });
    };

    app.controller("detalhesController", detalhesController)

}(angular.module("filmoteca")));

Aqui  usamos o serviço $routeParams, que permite retornar o conjunto atual de parâmetros à rota – no nosso exemplo, o Id do filme.

Se executarmos o projeto novamente, iremos obter o mesmo resultado, mas agora estamos usando um serviço criado para encapsular as funcionalidades da Web API e, assim, poderemos reusar o serviço caso precisemos:

macoratti

Acima, vemos a apresentação dos filmes e a exibição dos detalhes de um filme.

Na próxima parte do artigo, vamos implementar as funcionalidades para deletar, editar e criar filmes em nossa aplicação SPA.