Angular 2 - Cadastro de Clientes - XV


 Neste artigo vou mostrar como criar um cadastro de clientes e fazer o CRUD usando o Angular 2 e o Visual Studio Code.

Neste artigo vou abordar o envio ou submit do formulário e o evento ngSubmit. (link do artigo anterior)

Nosso template html cliente-detalhe.componente.html, que representa o nosso formulário, possui o botão Salvar que é do tipo Submit. Quando este botão for clicado ele irá submeter(enviar) o formulário :

...
  <button type="submit" class="btn btn-success" [disabled]="!clienteForm.form.valid">Salvar</button>
     <a class="btn btn-secondary" routerLink="/">Voltar </a>
...

Assim no ínício do formulário vamos usar um Event Binding para podermos 'escutar' este evento, ou seja quando o formulário for submetido vamos realizar alguma tarefa.

Nota : O Event binding nos permite enviar informações da view para a classe de componentes e essas informações em geral envolvem um clique, um passe de mouse ou uma teclagem.

Para isso vamos usar o ngSubmit e definir o método - onSubmit() - que vai ser executado quando o formulário for submetido.

<div class="container"> 
<h2>Salvar Cliente</h2>

<form (ngSubmit) = "onSubmit()" #clienteForm="ngForm" novalidate>
...

Agora na classe do nosso componente - cliente-detalhe.componente.ts - vamos definir o método 'onSubmit()'.

Vamos aproveitar e tratar duas abordagens quando o formulário for submetido:

  1. A inclusão de um novo cliente
  2. A alteração de um cliente existente.

Para isso vamos definir uma variável chamada isNovo que vai ser igual a true quando fizermos uma inclusão e false quando for uma alteração.

Inclua o código realçado em azul no arquivo de componente - cliente-detalhe.componente.ts - conforme abaixo:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params} from '@angular/router';
import { Location } from '@angular/common';
import { Cliente } from './cliente.model';
import { ClienteService } from './cliente.service';
@Component({
    moduleId: module.id,
    selector : 'cliente-detalhe',
    templateUrl : 'cliente-detalhe.component.html'   
})
export class ClienteDetalheComponent implements OnInit  {
      cliente : Cliente;
     //estamos incluindo um novo cliente
      private isNovo : boolean= true;
      constructor(
         private clienteService : ClienteService,
         private route : ActivatedRoute,
         private location : Location
      ) {}
       ngOnInit(): void {
           this.cliente = new Cliente(0,'','','',);
           this.route.params.forEach((params: Params)=>{
               let id: number = +params['id'];
          if(id){
           //se o id do cliente existe então estamos alterando
           this.isNovo = false;
           this.clienteService.getCliente(id)
               .then((cliente: Cliente)=> {
                    console.log(cliente);
                    this.cliente = cliente;
               });
          }
        });
    }
    getFormGroupClass(isValid : boolean, isPristine: boolean) : {} {
        return {
            'form-group' : true,
            'has-danger': !isValid && !isPristine,
            'has-success': isValid && !isPristine
        };
    }
    getFormControlClass(isValid : boolean, isPristine: boolean) : {} {
        return {
            'form-control' : true,
            'has-danger': !isValid && !isPristine,
            'has-success': isValid && !isPristine
        };
    }
    // será executado quando o formulário for submetido
    onSubmit() : void {
        if (this.isNovo) {
            console.log('cadastrar');
        } else {
            console.log('alterar');
        }
    }
}

Implementamos assim o método onSubmit() de forma a tratar as alterações e inclusões.

Se você executar a aplicação pode testar a lógica implementada ao clicar no botão Salvar para incluir e alterar dados de um cliente visualizando no log as ações disparadas:

Tudo bem, agora falta implementar a lógica para cadastrar e para alterar, e para isso vamos criar uma API simulada.

Essa tal API vai simular requisições HTTP como se estivéssemos em um servidor real, e vai salvar as nossas informações na memória. (Mais adiante você pode buscar as informações do servidor)

Para isso vamos precisar importar o módulo http e vamos fazer isso no arquivo app.module.ts conforme mostrado a seguir :

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { AppRoutingModule} from './app-routing.module';
import { ClientesModule } from './clientes/clientes.module';
@NgModule({
    imports : [AppRoutingModule, BrowserModule, ClientesModule, HttpModule ],
    declarations :[AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}

Após isso vamos criar um novo arquivo, na raiz da pasta app, que será a nossa API simulada.

Vamos chamar esse arquivo de in-memory-data.service.ts e vamos definir o código abaixo neste arquivo:

import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Cliente } from './clientes/cliente.model';
export class InMemoryDataService implements InMemoryDbService {
    createDb() : {} {
        let clientes : Cliente[] = [
            {id:1, nome: 'Jose C Macoratti', email:'macoratti@yahoo.com',telefone: '(21) 9987-6666'},
            {id:2, nome: 'Paulo Lima', email:'paulolima@yahoo.com',telefone: '(31) 9787-3333'},
            {id:3, nome: 'Suzana Ribeiro', email:'suzana@net.com',telefone: '(41) 8887-4444'},
            {id:4, nome: 'Paola Fernandes', email:'paolafernand@hotmail.com',telefone: '(13) 8987-5555'},
            {id:5, nome: 'Amelia Souza', email:'amelia@bol.com.br',telefone: '(11) 9808-7777'}
         ];
         return {clientes};
    }
}

Neste código criamos a classe InMemoryDataService que implementa o método createDb() da interface InMemoryDbService do pacote  'angular-in-memory-web-api' do Angular 2.

Nota:  A utilização do  'angular-in-memory-web-api'  faz com que o módulo http faça as requisições para a nossa API simulada.

Esta classe esta retornando os dados dos clientes e representa a nossa API simulada.

Agora temos que usar a API e vamos definir isso no arquivo app.module.ts :

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
import { AppComponent } from './app.component';
import { AppRoutingModule} from './app-routing.module';
import { ClientesModule } from './clientes/clientes.module';
@NgModule({
    imports : [AppRoutingModule, 
               BrowserModule, 
               ClientesModule, 
               HttpModule, 
               InMemoryWebApiModule.forRoot(InMemoryDataService) 
               ],
    declarations :[AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}

Com essas implementações o nosso serviço já vai poder fazer chamadas HTTP para a nossa API simulada graças ao módulo angular-in-memory-web-api.

Vamos então ver se a nossa API esta funcionando buscando a lista de clientes através da API.

Para fazer isso vamos abrir o arquivo cliente.service.ts e incluir o código destacado em azul :

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Cliente } from './cliente.model';
import { CLIENTES } from './clientes-mock';
@Injectable()
export class ClienteService{
   // app é a pasta de onde fizermos a chamada
   // clientes é o nome da variável na classe InMemoryDataService
   private clientesUrl : string = 'app/clientes';
    constructor(
       private http: Http
    ) {}
    getClientes() : Promise<Cliente[]> {
       return this.http.get(this.clientesUrl) 
         .toPromise()
         .then(response => response.json().data as Cliente[])
       //return Promise.resolve(CLIENTES);        
      }

    getCliente(id:number): Promise<Cliente> {
           return this.getClientes()
           .then((clientes: Cliente[]) => clientes.find(cliente => cliente.id === id)); 
          }
}

Vamos entender o que foi feito:

- Em nossa classe ClienteService() esta retornando uma promise que passa a nossa lista de clientes através da importação de um arquivo. Vamos comentar essa linha de código pois agora vamos fazer uma chamada via HTTP :  //return Promise.resolve(CLIENTES);

- Para fazer chamadas via HTTP precisamos importar o módulo http: import { Http } from '@angular/http';

- Vamos precisar importar o operador toPromise da biblioteca rxjs para poder usar o toPromise e converter o Observable retornado pelo método Get : import 'rxjs/add/operator/toPromise';

- Vamos injetar o http em nosso serviço usando o construtor :

    constructor(
          private http: Http
    ) {}

Como

- Vamos definir a url de acesso ao nosso recurso que é a lista de clientes:  private clientesUrl : string = 'app/clientes';

- A seguir vamos fazer a requisição http Get usando a url do recurso definida e retornando um observable que convertemos em uma promise usando ToPromise e a seguir , ao obter a resposta convertemos para o formato json ( response.json() ) como uma lista de clientes representada pelo array Cliente[] :

 getClientes() : Promise<Cliente[]> {
       return this.http.get(this.clientesUrl) 
         .toPromise()
         .then(response => response.json().data as Cliente[])
       //return Promise.resolve(CLIENTES);        
      }

Feito isso podemos executar a aplicação e vemos a nossa lista de clientes retornada a partir da nossa API simulada.

Dessa forma delegamos o acesso aos dados a um serviço reutilízável sem precisar fazer grandes alterações no código.

No próximo artigo vamos abordar o tratamento de erros.

Pegue o código do projeto aqui : cadastro_clientes.zip ( a pasta cadastro sem a pasta node_modules)

(Disse Jesus) - 'Aquele que tem os meus mandamentos e os guarda esse é o que me ama; e aquele que me ama será amado de meu Pai, e eu o amarei, e me manifestarei a ele.'
João 14:21

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti