Baixe o app para aproveitar ainda mais
Prévia do material em texto
10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 1/34 FERRAMENTAS DE DESENVOLVIMENTO WEB AULA 6 Prof. Yanko Costa 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 2/34 CONVERSA INICIAL O desenvolvimento de uma aplicação SPA é muitas vezes composto por diferentes partes, que envolvem a apresentação de informações e interação com o usuário, a comunicação com o servidor para busca de dados atualizados e o processo de integração dessas diferentes partes da aplicação. Nesta aula, vamos acrescentar funções em nosso protótipo, que até o momento apenas mostra uma informação estática. Apesar de permitir verificar o fluxo de funcionamento do Angular, nossa aplicação Angular ainda não trouxe a automação que se espera em um programa. Demonstraremos como flexibilizar a exibição das informações na tela como uso de atributos específicos do Angular. Vamos criar um ambiente de servidor para alimentar nossa aplicação e estudar os mecanismos de comunicação HTTP. Criaremos formas de consumir informações de um servidor usando funções do JavaScript e vamos verificar como montar um formulário que pode ser usado para enviar dados para o servidor. Também vamos verificar como estruturar nossa aplicação Angular criando componentes que possam ser chamados pela rotina principal e cada um poderá tratar de partes específicas da tela. Por fim, vamos instalar nossa aplicação SPA Angular como uma aplicação no dispositivo móvel, usando os conceitos de PWA vistos em aulas anteriores. TEMA 1 – ANGULAR VIEW Para desenvolver uma aplicação Angular, precisaremos acrescentar maior dinamismo na aplicação e para isso, evitar as informações estáticas codificando nossa automação em TypeScript. Usaremos o conteúdo estático de aulas anteriores e faremos algumas modificações para tornar o conteúdo mais genérico e automatizado. Ele servirá para demonstrar o uso de recursos de visualização e processamento criados pelo Angular. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 3/34 1.1 TEMPLATES No Angular, as informações que são apresentadas em HTML fazem parte de uma estruturação do framework para o uso de templates (Templates, [S.d.]). Estes templates são um esqueleto que pode abrigar variáveis e pequenos algoritmos que facilitam a listagem de dados. Inicialmente, temos a possibilidade de incluir no HTML variáveis que vão ser convertidas para seu conteúdo assim que a tela for apresentada ao usuário. Essa possibilidade deixa o HTML mais genérico, evitando ter de ser alterado a cada processamento. Para acrescentar as variáveis no template, basta incluir as duplas chaves de início "{{", mais a variável e as duplas chaves de fim "}}". A partir do index.html, que tem a parte inicial da aplicação, o Angular vai combinando os demais arquivos HTML até formar a aplicação completa (ver Figura 1). Por esse motivo os demais templates não precisam ter as tags iniciais <html>, <head> e <body>. Figura 1 – Vinculação dos templates Além de apresentar as variáveis, os templates HTML têm formas de vincular as informações, sendo incluídas pelos usuários em formulários com variáveis e utilizadas nos códigos internos da aplicação, fornecendo uma maneira mais simples de manter os dados sincronizados. 1.2 REPETIÇÃO 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 4/34 Para permitir que grupos de dados sejam facilmente listados nas estruturas do HTML, o template Angular inclui o atributo “*ngFor”, que vai criar um laço de repetição que multiplicará as tags HTML envolvidas. Para testar essa opção, vamos incluir uma estrutura com as faturas e seus dados principais e salvar como “faturas.ts” na pasta “app” (ver Quadro 1). Quadro 1 – Repetição de tag <li> com informações de um array a) export const faturas = [ { cod: 1, empresa: "Empresa de Alcool Gel Ltda", valor: 2560, dt_vencto: "21/06/2020", dt_pgto: "22/06/2020", nf: 145 }, { cod: 2, empresa: "Transportes SA", valor: 1680, dt_vencto: "16/11/2020", dt_pgto: "16/11/2020", nf: 1024 }, { cod: 3, empresa: "Industria de Cimentos SA", valor: 8150, dt_vencto: "14/03/2021", dt_pgto: "", nf: 32 }, { cod: 4, empresa: "Editora Book Ltda", valor: 6500, dt_vencto: "15/07/2020", dt_pgto: "15/07/2020", nf: 66 }, b) <ol> <li *ngFor=" let fatura of lista_faturas"> {{ fatura.empresa }} </li> </ol> c) 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 5/34 { cod: 5, empresa: "Restaurante bandejão Eireli", valor: 977, dt_vencto: "05/02/2021", dt_pgto: "", nf: 233 } ]; No Quadro 1, em (a) temos os dados que serão utilizados em alguns exemplos. Eles devem ser incluídos no "app.component.ts" por meio de uma declaração de importação "import { faturas } from './faturas';" e depois associada a uma variável (lista_faturas = faturas;). Ao executar o aplicativo como visto em aulas anteriores, ele será compilado, e o HTML mostrado em (b) será incluído na aplicação e o “*nfFor” será executado, repetindo a linha da tag <li> mostrando o conteúdo de “{{ fatura.empresa }}” a cada repetição. O resultado é apresentado em (c). O Quadro 2 mostra uma variação do exemplo com o acréscimo de mais uma variável (fatura.valor) e a utilização de estilos para a formação das informações. Quadro 2 – Repetição de tag HTML com o uso de estilos <ol> <li *ngFor=" let fatura of lista_faturas"> Empresa: {{ fatura.empresa }} , valor: <span style="color: blue">{{ fatura.valor }} </span> </li> </ol> Os templates podem conter também tags de formatação criadas no arquivo app.component.css, que é criado com a aplicação. 1.3 DECISÃO Somado à possibilidade de repetição automatizada de trechos do HTML, temos também como decidir se uma tag será incluída ou não na tela, com base no conteúdo de variáveis. O Angular tem o atributo “*ngIf”, que determina se a tag na qual ele se encontra será incluída na montagem da tela (ver Quadro 3). 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 6/34 Quadro 3 – Decisão sobre inclusão de fatura com base na data de pagamento <ol> <div *ngFor=" let fatura of lista_faturas"> <li *ngIf="fatura.dt_pgto!=''"> Empresa: {{ fatura.empresa }} , valor: <span style="color: blue">{{ fatura.valor }} </span> </li> </div> </ol> No exemplo do Quadro 3, temos a mesma repetição que mostrará as faturas do array “lista_faturas”. Mas, nesse caso, a linha da tag <li> só será incluída caso a condição usada no “*ngIf” seja verdadeira, ou seja, fatura.dt_pgto precisa ser diferente de vazio. Por esse motivo, não são apresentadas as empresas Indústria de Cimentos SA e Restaurante Bandejão Eireli no Quadro 3. Os templates podem também pode conter seletores de framework como o Bootstrap apresentado anteriormente em nossos estudos. No Quadro 4, temos nossa tabela de faturas novamente sendo apresentada, mas dessa vez as informações estão em um array que pode ter a quantidade de dados aumentados ou diminuídos sem que seja necessário alterar o template HTML. Quadro 4 – Formatação de templatecom bootstrap, *ngFor e *ngIf <h3>FATURAS PAGAS</h3> <table class='table table-striped'> <thead> <tr><th>Empresa</th><th>Valor</th></tr> </thead> <tbody> <ng-container *ngFor=" let fatura of lista_faturas"> <tr *ngIf="fatura.dt_pgto!=''"> <td>{{ fatura.empresa }} </td> <td> <span style="color: blue">{{ fatura.valor }}</span> </td> </tr> </ng-container> </tbody> </table> 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 7/34 No Quadro 4, as tabelas estão agrupadas conforme a verificação da data de pagamento. As empresas que não têm data de pagamento registrada são as que estão pendentes e formam uma <table> específica. Desta forma o "*ngIf" foi utilizado para diferenciar o conteúdo a ser mostrado em cada aba criada pelo Bootstrap. 1.4 FILTROS (PIPES) Durante a exibição dos dados, a formatação pode trazer uma maior facilidade na interpretação das informações. Por esse motivo, temos no Angular filtros que podem converter os dados para um formato visualmente mais interessante. No Quadro 5, temos um exemplo de uso de filtro para formatar os valores colocando as casas decimais e o ponto de milhar. Quadro 5 – Filtros nos valores <ng-container *ngFor=" let fatura of lista_faturas"> <tr *ngIf="fatura.dt_pgto!=''"> <td>{{ fatura.empresa }} </td> <td class="text-right" > <span style="color: blue;">{{ fatura.valor | number : '1.2-2' }}</span> </td> <td> {{ fatura.dt_pgto}} </td> </tr> </ng-container> No exemplo do Quadro 5, o conteúdo de fatura.valor passa por um filtro number que possui uma indicação (1.2-2) de que o valor conterá pelo menos um valor antes da casa decimal e um mínimo de duas casas decimais e poderá ter no máximo duas casas decimais (valor-antes.casas- mínimas-casas-máximas). O Angular possui alguns filtros para dados que são frequentemente utilizados, como: a. DatePipe: utilizado para transformar as datas, podendo fazer a separação de meses, dias e anos; b. UpperCasePipe: converte o texto para maiúsculas; c. LowerCasePipe: converte o texto para minúsculas; 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 8/34 d. CurrencyPipe: apresenta o valor como uma informação financeira, usando, inclusive, o símbolo da moeda no país específico; e. DecimalPipe: converte o valor para string com a pontuação de casas decimais; f. PercentPipe: converte o número em uma string com o sinal de percentual. Muitas informações possuem características de formatação diferentes entre países. Uma determinada região pode separar as casas decimais com vírgula ou ponto e as moedas utilizadas em cada país pode conter uma abreviação específica ou um posicionamento diferenciado. Para essas características específicas dos países existe uma padronização, normalmente associado com a abreviação i18n e esse esquema de internacionalização é implementado em diversas linguagens de programação. Para que os valores possam ter as casas decimais separadas por vírgulas e o separador de milhar com ponto, no caso do Angular, temos que configurá-lo para a região do Brasil. No Quadro 6, temos as configurações necessárias para isso, que devem ser acrescentadas no “app.module.ts”. Quadro 6 – Configuração de internacionalização para região brasileira // ---- localização - pt-BR import { LOCALE_ID } from '@angular/core'; import { registerLocaleData } from '@angular/common'; import ptBR from '@angular/common/locales/pt'; registerLocaleData(ptBR); //--- no @NgModule providers: [ {provide: LOCALE_ID, useValue: 'pt' } ], Como padrão, o Angular sempre iniciará com a configuração da região norte-americana “us”. Por esse motivo, o uso de filtro nos valores será mostrado com vírgula no milhar e ponto na casa decimal. TEMA 2 – BACKEND COM NODEJS Normalmente os sistemas consultam bases de dados para trazer informações atualizadas para os usuários. Essas bases podem conter milhares de registros sobre diferentes contextos e tipos de dados 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 9/34 e, conforme for a situação, esses dados podem ser atualizados diversas vezes num segundo. Transações financeiras, posições geográficas, produtos à venda, agendamentos de pacientes, matrículas em cursos, variação de temperatura, níveis de oxigenação, são alguns exemplos de dados que podem ser coletados, armazenados e atualizados, variando a frequência com que são manipulados. Por serem acessados de diferentes formas, essas bases podem centralizar os dados de diferentes sistemas. A mesma base que organiza as notas fiscais de vendas de uma empresa por meio de um sistema ERP pode ter as informações de faturamento sendo consultados por um aplicativo de um smartphone ou a lista de produtos em estoque verificados por um sistema de e-commerce desta mesma empresa (ver Figura 2). Figura 2 – Base de dados centralizada com acessos diversos Por esse motivo, é importante estudar o cenário de acesso a dados via rede e que vão alimentar a tela de um aplicativo SPA. Em nossas primeiras aulas, verificamos algumas tecnologias usadas nos sistemas web, como o protocolo HTTP, e conceitos como o cliente-servidor e usaremos esse conhecimento ao montar nosso ambiente de backend. Saiba mais 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 10/34 Backend é um termo muito utilizado para designar as tecnologias que ficam fora do conhecimento do usuário, mas que dão suporte aos demais sistemas, como base de dados, sistemas intermediários (middleware) e servidores. Para nossa aplicação Angular, para coletar informações de um servidor utilizaremos o Node.js, que não serve apenas para executar o utilitário de criação e manutenção do angular ("ng"). Muitos sistemas são desenvolvidos com Node.js e uma das suas vantagens é o desempenho em aplicações web no servidor com o uso de HTTP. 2.1 CRIANDO UM SERVIDOR HTTP O Node.js possui um módulo padrão para acesso via protocolo HTTP, como podemos ver no exemplo do Quadro 7, que também cria uma estrutura com informações de faturas, igual à utilizada nos exemplos anteriores. Quadro 7 – Servidor HTTP com Node.js com envio de estrutura JSON const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const lista_faturas = [ { cod: 1, empresa: "Empresa de Alcool Gel Ltda", valor: 2560, dt_vencto: "21/06/2020", dt_pgto: "22/06/2020", nf: 145 }, { cod: 2, empresa: "Transportes SA", valor: 1680, dt_vencto: "16/11/2020", dt_pgto: "16/11/2020", nf: 1024 } 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 11/34 ]; const server = http.createServer( (req, res) => { res.statusCode = 200; var faturas_json = JSON.stringify( lista_faturas ); //header CORS+json res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); res.writeHead( 200, { 'Content-Type': 'application/json'} ); res.write( faturas_json ); console.log( faturas_json ); res.end( ); }); server.listen(port, hostname, () => { console.clear(); console.log(`Server running at http://${hostname}:${port}/`); }); Com o código salvo em um arquivo com nome de web.js, por exemplo, podemos executar o servidor digitando na linha de comando: “node web.js”.O programa será executado e mostrará a frase “Server running at http://127.0.0.1:3000/”, iniciando a espera de contato na porta 3000 na máquina local (localhost ou 127.0.0.1). Esse é um típico comportamento de um servidor: ficar aguardando uma conexão para iniciar seu trabalho. Em nosso caso, o servidor converterá nosso objeto literal lista_faturas em uma string com “JSON.stringify( lista_faturas )”. Na sequência, ele cria um cabeçalho HTTP de resposta indicando a liberação de acesso do endereço de origem “http://localhost:4200” e que será enviado um conteúdo JSON. Ao executar “res.write( faturas_json )”, os dados são preparados e com “res.end( )” ele é enviado para quem solicitou o contato. Um teste pode ser realizado com um navegador, apontando para “http://localhost:3000” e o resultado será o da Figura 3. Figura 3 – Resultado do acesso ao servidor HTTP do Node.js 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 12/34 Na Figura 3, o resultado do acesso ao servidor é apresentado com a identificação dos campos do JSON, que vimos em aula anterior. Dependendo do navegador, podemos ter opções de visualização dos dados em formatos diferentes para facilitar a interpretação dos dados. No Quadro 7, temos também uma forma enxuta de criar uma função: “http.createServer( (req, res) => { } )”. Nesse formato, não é digitado o termo function nem o nome da função, sendo inserida uma flecha “=>” para indicar o bloco da função. Por causa dessa flecha (arrow, em inglês) esse formato é chamado de arrow functions”. Várias bibliotecas no Node.js e também no TypeScript utilizam esta sintaxe em suas documentações e exemplos. No “http.createServer( função )”, a função definida como parâmetro será chamada a partir de um evento. 2.2 MYSQL Outra importante funcionalidade de nosso backend é compartilhar o acesso a uma base de dados. Em nosso cenário, teremos uma base de dados utilizando o sistema gerenciador Mysql, muito utilizado em sistemas web de pequeno a grande porte. No Quadro 8 foi montado um exemplo de acesso a uma tabela no Mysql, que, por sua vez está instalado no servidor local (localhost), utilizando a porta TCP padrão do Mysql (3306), e lista também o comando para criação da tabela “faturas” e seus campos. Saiba mais O banco de dados Mysql, apesar de atualmente pertencer à empresa Oracle, é opensource, tem grande desempenho e é utilizado até mesmo por grandes sistemas web como os da Neftflix, 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 13/34 Tesla, Airbnb, ebay e Facebook. Quadro 8 – Acesso à base Mysql com Node.js const mysql = require('mysql'); var faturas_json = ''; var con = mysql.createConnection({ host: "localhost", user: "root", password: "tmpsenha", database: "webANG" }); sql = "select * from faturas"; con.connect( function(err) { if (err) throw err; console.log("Connected!"); con.query(sql, function (err, result, fields) { if (err) throw err; faturas_json = JSON.stringify(result); console.clear(); console.log( faturas_json ); con.end(); }); }); No exemplo ao lado, o Node.js vai estabelecer uma conexão com o sistema do Mysql (que executa de forma independente do Node.js) usando a declaração “mysql.createConnection” com as configurações básicas de acesso como usuário, senha e nome da base. O comando SQL que será enviado para o Mysql processar está na variável “sql” e solicita uma listagem de todos os registros da tabela “faturas”. O resultado é um JSON que será convertido para string e mostrado por meio do comando “console.log( faturas_json )”. use webANG; Create table faturas ( cod Int UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT, empresa Varchar(30) NOT NULL, valor float NOT NULL, dt_vencto date, dt_pagto date, nf Int unsigned , Primary Key (cod)) ENGINE = MyISAM; Com o código do Quadro 8, temos o Node.js preparado para executar vários tipos de solicitações SQL. Mas, apesar de facilmente visualizado o resultado na linha de comando com o uso do “console.log()”, devemos lembrar que, ao criar uma aplicação SPA, ela será executada no dispositivo cliente e a base de dados estará em outro equipamento, ou seja, o resultado de “console.log()” não será visível. 2.3 HTTP E MYSQL 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 14/34 Unindo a capacidade de comunicação via HTTP e o acesso à base de dados, temos o código apresentado no Quadro 9, que acessará a tabela “faturas” e enviará o resultado via HTTP para o solicitante. Quadro 9 – Enviando resultado de consulta SQL por HTTP const mysql = require('mysql'); const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer( (req, res) => { res.statusCode = 200; var faturas_json = ''; var con = mysql.createConnection( { host: "localhost", user: "root", password: "tmpsenha", database: "webANG" }); sql = "select * from faturas"; con.connect( function(err) { if (err) throw err; console.log("Connected!"); con.query(sql, function (err, result, fields) { if (err) throw err; faturas_json = JSON.stringify( result ); //header CORS+json res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); res.writeHead( 200, { 'Content-Type': 'application/json'} ); res.write( faturas_json ); res.end( ); con.end(); }); }); }); server.listen(port, hostname, () => { console.clear(); console.log(`Server running at http://${hostname}:${port}/`); 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 15/34 }); Com poucas linhas o código fonte de criação de servidor HTTP acrescentou a consulta da base Mysql no momento em que vai processar a solicitação. Por sua vez, assim que o processamento é finalizado no servidor Mysql, é feita a conexão de resposta para o solicitante. É importante destacar esse mecanismo, pois o Node.js trabalha de forma assíncrona e não aguarda o processamento finalizar para passar para a próxima linha de código. Ele associa uma função a um evento, de forma que, quando acontece a finalização de algum processamento, a função associada é executada. Em nosso exemplo do Quadro 9, quando o servidor HTTP recebe a solicitação em “http.createServer”, ele executa uma função com o “mysql.createConnection”. Quando a conexão com o Mysql é estabelecida em “con.connect”, ele aciona a função que contém “con.query”, que aguarda o processamento e quando chega a resposta ele aciona a função que preparará os cabeçalhos HTTP e dos dados a serem enviados com o comando “con.end()”. Na programação assíncrona, se não houver alguma forma de acionar essas funções com base nos eventos, considerando que a execução do JavaScript pelo Node.js é mais rápido que o acesso externo (mesmo que esse acesso leve milissegundos), todo código poderia ter sido executado antes de receber aquele primeiro sinal de criação do servidor HTTP. TEMA 3 – ACESSO AO SERVIDOR Em uma aplicação Angular, conforme representado na Figura 2, podemos necessitar atualizar algum valor com base em um servidor e, considerando que nossa aplicação é executada no dispositivo cliente, temos que ter a opção no JavaScript para esse tipo de acesso remoto. Essa comunicação vem do Ajax (Asynchronous JavaScript and XML), um termo usado para indicar que o JavaScript irá se comunicar com o servidor diretamente de forma assíncrona, utilizando comobase o objeto XMLHttpRequest (Deitel; Deitel, 2009, p. 314). Saiba mais Apesar de ter o XML no nome, podem ser utilizados diferentes formatos de dados na transmissão das informações via XMLHttpRequest. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 16/34 O Angular possui um modulo padrão para acesso ao protocolo HTTP que abstrai uma série de particularidades desse tipo de comunicação chamado de HttpClient. Com ele podemos acessar o servidor para consultar informações, enviar dados coletados de usuários ou enviar arquivos. 3.1 CONSUMINDO UM JSON VIA HTTP Vamos criar uma pequena aplicação Angular para testar o acesso remoto via HTTP, iniciando com a configuração de um novo projeto chamado de web: ng new web. Com o projeto criado, entrar na pasta src/app e acrescentar no arquivo app.module.ts as linhas do Quadro 10. Quadro 10 – Importação e configuração do módulo HttpClientModule import { HttpClientModule } from '@angular/common/http'; ... imports: [ BrowserModule, HttpClientModule ], No Quadro 11, em (a) temos as linhas a serem acrescentadas ao conteúdo de “app.component.ts” para acessar o servidor “http://localhost:3000”. Iniciando com a importação de OnInit, que vai possibilitar executar alguma ação quando o aplicativo finalizar seu carregamento. Em seguida, temos a importação do HttpClient, que vai fornecer as funções necessárias para estabelecer a conexão e solicitar informações ao servidor. No corpo da classe de nossa aplicação temos a criação de uma função “getFaturas()”, que irá agrupar todos os comandos de acesso e consulta do servidor. Essa função é executada automaticamente assim que a aplicação terminar de ser carregada no navegador. Em “this.http.get( url ).subscribe( )”, temos a linha que faz o acesso ao servidor e inclui uma função anônima que executará quando o servidor terminar de processar e responder a solicitação. Nesta função o parâmetro res contém os dados da resposta do servidor com os dados em formato JSON (é o padrão se nada for alterado). O resultado é passado a variável “lista_faturas” e também listado no console do navegador. Quadro 11 – Criando aplicação Angular com acesso a servidor remoto a) b) 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 17/34 import { OnInit } from '@angular/core'; import { HttpClient } from "@angular/common/http"; export class AppComponent implements OnInit { title = 'web'; lista_faturas:any = []; constructor(private http: HttpClient) { } getFaturas() { const url ='http://localhost:3000'; this.http.get( url ).subscribe( (res)=>{ this.lista_faturas = res; console.log(this.lista_faturas ); }); } ngOnInit() { this.getFaturas(); } } <ol> <div *ngFor="let fatura of lista_faturas" > <li> {{ fatura.empresa }} - {{ fatura.valor }} - {{ fatura.dt_vencto }} </li> </div> </ol> No Quadro 11, em (b), temos a listagem do arquivo “app.component.html” com uma lista ordenada simples, com os campos recebidos no JSON do servidor. 3.2 FORMULÁRIOS NO ANGULAR Enquanto as consultas no servidor podem trazer as informações atualizadas que precisamos para apresentar ao usuário, por vezes será necessário utilizar algum dado informado (ou selecionado) pelo usuário para ser enviado para o servidor armazenar na base de dados ou usar como parâmetro para consultas personalizadas. No Quadro 12, temos um exemplo de formulário com campos em que o usuário vai digitar novos dados e selecionar uma opção, finalizando com o clique no botão que envia as informações para processamento. No início do formulário, temos a indicação de qual função será executada para processar o formulário: “envia( )”. Mais abaixo, em destaque, temos o <input>, que pede para o usuário digitar o endereço de e-mail com um adicional do template do Angular que vincula a variável do <input> com 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 18/34 a variável do TypeScript usando o [(ngModel)]="email". Dessa forma, quando o usuário digitar algo, o Angular vai sincronizar o conteúdo com a variável “email”, que também poderá ser vista no formulário com o “{{ e-mail }}”. O mesmo será feito com a seleção usando o tipo radio. Ao final do formulário, temos uma <div>, que tem um atributo que está condicionado a variável enviado ( [hidden]="!enviado" ). Esse atributo indica que a <div> estará escondida (hidden) quando o conteúdo da variável for falso (ou seja, o conteúdo não foi enviado). Quando o usuário clicar para enviar as informações do formulário, a condição inverte e a <div> fica visível, mostrando as variáveis que foram enviadas para conferência. Quadro 12 – Formulário para notificação de eventos <h3> Notificação sobre Eventos online </h3> <form #eventosForm="ngForm" (ngSubmit)="envia( )"> <div> <label for="email"> Informe seu E-mail: </label> <input name="email" type="text" [(ngModel)]="email"> {{ email }} </div> <div> <label for="propaganda"> Você aceita receber propaganda? </label> <input type="radio" value="sim" name="propaganda" [(ngModel)]="propaganda"> Sim <input type="radio" value="nao" name="propaganda" [(ngModel)]="propaganda"> Não </div> <button class="button" type="submit">Cadastra</button> </form> <br> <div style="background-color: lightgray" [hidden]="!enviado"> <b>Dados enviados:</b><br> {{ revisar }} <button (click)="enviado=false">Desliga</button> </div> Na Figura 4, temos a tela construída pelo Angular ao acessar o servidor de teste (http://localhost:4200). 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 19/34 Figura 4 – Tela de notificação de eventos Para processar o formulário, temos o código listado no Quadro 13, que deve ser incluído no “app.component.ts”. Em destaque, as variáveis que vão ser utilizadas para armazenar os dados do formulário e como sinalização de envio e, na sequência, a função “envia( )”, que vai ser processada ao clicar no botão de submit. Dentro da função “envia( )”, temos três destaques: a. o primeiro é a troca do estado da variável “enviado” para “verdadeiro”. Nesse caso, mudará a visibilidade da <div> do formulário; b. Em seguida, a montagem da string que será enviada ao servidor. Essa string deve obedecer ao formato e aos símbolos que o HTTP usa para a identificação das variáveis e os conteúdos. Após entender como funciona o formato, o leitor poderá utilizar bibliotecas que auxiliam nessa tarefa, pois alguns conteúdos podem se tornar mais trabalhosos para formatar; c. O outro destaque é a linha que executará o envio das informações (“campos”) para o servidor usando o método POST do HTML. Quadro 13 – Processamento do formulário de notificação no Angular import { Component } from '@angular/core'; import { HttpClient } from "@angular/common/http"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 20/34 title = 'form'; constructor( private http: HttpClient) { } //-- variaveis do form propaganda: string = ''; email: string = ''; enviado = false; envia( ) { this.enviado = true; const campos = "email="+this.email+"&propaganda="+this.propaganda ; const url ='http://localhost:3000';this.http.post(url , campos ).subscribe( ); } get revisar() { return "email="+this.email+"&propaganda="+this.propaganda } } No fim do código do Quadro 13, temos a função “revisar( )”, que está na <div> condicional do formulário. Ela exibirá o conteúdo das variáveis que foram enviadas para o servidor, mas, como visto acima, as informações somente serão visíveis quando a variável “enviado” for verdadeira. No Quadro 14, temos o código que deve ser executado pelo Node.js para criar um servidor que vai processar os dados enviados por meio do método POST do HTTP. Quadro 14 – Código Node.js com o tratamento do envio do formulário const http = require('http'); const qs = require('querystring'); const porta = 3000; http.createServer( ( req, res) => { console.clear() console.log ("-->Conectado!"); let dados = ''; req.on( 'data', parte => { dados += parte; }) req.on( 'end', ( ) => { 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 21/34 var formulario = qs.parse( dados ); console.log( formulario['email'] ); console.log( formulario.propaganda ); }) }).listen( porta ); console.log(`server running on port ${porta} `); Neste código, ao criar a instância do servidor e designar uma função anônima para processar algum evento na porta 3000, temos a utilização do objeto “request”, que mantém todas as informações da requisição ao servidor e que estará associado a variável “req”. Neste objeto, estão os cabeçalhos do protocolo assim como também os dados enviados pela aplicação, que serão capturados pelos dois comandos “req.on” em destaque. No primeiro “req.on”, temos a coleta dos dados enviados. Como não se sabe antecipadamente qual o tamanho destes dados, a cada trecho identificado com data, o “req.on” executa a função associada que por sua vez acrescenta o novo trecho de informação (variável parte) a variável data. Ao encontrar a identificação end, o “req.on” finaliza a coleta dos dados e vai processar as informações. Primeiramente ele precisa separar a string recebida para poder acessar as variáveis individualmente. Para isso, usa a função parse do módulo querystring. Após a separação, o conteúdo das variáveis pode ser acessado de duas formas, como exemplificado nas linhas seguintes ao imprimir no console as informações de “email” e da “propaganda” recebidas. TEMA 4 – INTEGRANDO A APLICAÇÃO ANGULAR Os tópicos do framework Angular exemplificados nas aulas foram apresentados de forma isolada ou simplificada para facilitar o entendimento do contexto sendo explicado. Para evoluir mais um pouco em seu uso, vamos verificar o procedimento para acrescentar componentes na aplicação e implementar uma função para solicitar dados personalizados ao servidor com base em opção selecionada pelo usuário e o processamento da resposta do servidor. Utilizaremos um servidor com acesso a banco de dados e com o processamento de dados via método POST, e em nossa aplicação Angular agregaremos os principais conceitos vistos, numa única aplicação. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 22/34 Nossa aplicação vai listar as faturas pagas e não pagas no componente inicial, e gerará uma lista das faturas pagas fora do prazo, no componente adicional. Para cada componente, uma consulta diferente ao servidor será necessária. Em uma das consultas será enviado o mês escolhido pelo usuário para restringir a busca no banco de dados. Na Figura 5, temos a visão geral da nossa proposta. Figura 5 – Diagrama da aplicação angular com dois componentes O layout da aplicação ficará conforme a Figura 6. Na parte principal, temos a tabela criada com Bootstrap semelhante à utilizada em outros exemplos. Na parte superior, será acrescentado um botão que, ao ser clicado, permitirá escolher o mês para a consulta. Figura 6 – Layout da aplicação com dois componentes 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 23/34 Na parte do servidor, teremos o recebimento das solicitações e, conforme a URL enviada (“/listafaturas” ou “/foradoprazo”), o servidor vai proceder com o acesso ao banco Mysql. O novo projeto foi criado com o comando “ng new app-fat” e foram adicionados os seguintes trechos de outros exemplos: a. No “index.html” – copiar a configuração do Bootstrap; b. No “app.module.ts” – o módulo de comunicação “HttpClientModule”, a configuração de internacionalização (“LOCALE_ID”) e o módulo de formulário “FormsModule”; c. No “app.component.ts” – importar o “HttpClient” e trazer o código de consulta da lista de faturas, mudando apenas a URL de chamada para “url ='http://localhost:3000/listafaturas';”; d. No “app.component.html” – copiar a tabela de faturas pagas e não pagas apresentada em aulas anteriores, acrescentar no início do arquivo a linha “<app-fat-foradoprazo></app- fat-foradoprazo>” e proceder aos ajustes exemplificados no Quadro 15. Quadro 15 – Ajustes no HTML do componente inicial <tr *ngIf="fatura.dt_pagto!='0000-00-00'"> <td>{{ fatura.empresa }} </td> <td class="text-right" > <span style="color: blue;">{{ fatura.valor | number : '1.2-2' }}</span> </td> <td> {{ fatura.dt_pagto | date: 'dd/MM/yyyy'}} </td> </tr> No código ao lado, alterar a condição para uma data vazia padrão do Mysql ("0000-00-00"). Acrescentar um filtro para a data. Proceder com o ajuste nas duas tabelas. E para deixar a parte do servidor preparada para as consultas, proceder à criação do código JavaScript para o Node.js do Quadro 16. Esse código usará a URL como indicador de qual consulta ao Mysql será executada: a consulta geral sem restrição, ou a consulta com o uso do “WHERE”. Quadro 16 – Código JavaScript para servidor Node.js const mysql = require('mysql'); const http = require('http'); const qs = require('querystring'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer( (req, res) => { 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 24/34 var faturas_json = ''; if (req.url == '/listafaturas') { var con = mysql.createConnection({ host: "localhost", user: "root", password: "tmpsenha", database: "webANG" }); sql = "select * from faturas "; con.connect( function(err) { if (err) throw err; console.log("Conectado: Mysql!"); con.query(sql, function (err, result, fields) { if (err) throw err; faturas_json = JSON.stringify(result); res.statusCode = 200; res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); res.writeHead( 200, { 'Content-Type': 'application/json'} ); res.write( faturas_json ); res.end( ); con.end(); }); }); } if (req.url == '/foradoprazo') { let data = ''; req.on('data', chunk => { data += chunk; }) req.on('end', () => { var formulario = qs.parse( data ); if (formulario.mes != "" && formulario.mes != null) { var con = mysql.createConnection({ host: "localhost", user: "root", password: "tmpsenha", database: "webANG" }); sql = "select * from faturas where dt_vencto <> dt_pagto and month(dt_vencto) = "+formulario.mes; 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 25/34 con.connect( function(err) { if (err) throwerr; console.log("Conectado: Mysql!"); con.query(sql, function (err, result, fields) { if (err) throw err; faturas_json = JSON.stringify(result); res.statusCode = 200; res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); res.writeHead( 200, { 'Content-Type': 'application/json'} ); res.write( faturas_json ); res.end( ); con.end(); }); }); } }); } }); server.listen(port, hostname, () => { console.clear(); console.log(`Server running at http://${hostname}:${port}/`); }); Após criado o código do Quadro 16, você deve salvar o arquivo com o nome “app-fat.js”, por exemplo, e executar com o comando: “node app-fat.js”. 4.1 CRIANDO UM NOVO COMPONENTE No Angular, uma aplicação é composta por componentes que encapsulam o HTML, o CSS e o TypeScript, que mostrarão as informações para o usuário conforme já estudamos. Até agora, usamos como referência projetos criados com “ng”, que possuem apenas o componente inicial (<app-root>) para exibir as informações na tela. Mas, à medida que nossa aplicação tem suas funcionalidades aumentadas, é conveniente separar cada parte visual da tela em componentes que permitam melhor controle, facilitando a manutenção e aumentando a probabilidade de reutilização dos componentes. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 26/34 Para acrescentar um novo componente, o comando ng pode ser utilizado para simplificar a configuração, digitando na linha de comando “ng generate component fat-foradoprazo”. Uma nova pasta será criada dentro de “app” com os arquivos “.ts”, “.css”, “.html” do novo componente. Nesse novo componente, teremos as seguintes alterações indicadas no Quadro 17. Quadro 17 – Códigos do componente para consulta das faturas fora do prazo a) "fat-foradoprazo.component.html" <div class="btn btn-primary btn-icon-split"> <span class="icon text-white-50"> <i> >> </i> </span> <button data-toggle="collapse" data-target="#inclui" class="btn btn-primary"> Lista faturas pagas fora do prazo ... </button> </div> <div id="inclui" class="collapse"> <div> <form #mesForm="ngForm" (ngSubmit)="envia()" class="form- inline"> <div> <label for="mes"> Selecione o mês: {{ mes }} </label> <select name="mes" [(ngModel)]="mes" required> <option value="01">Janeiro</option> <option value="02">Fevereiro</option> <option value="03">Março</option> <option value="04">Abril</option> <option value="05">Maio</option> <option value="06">Junho</option> <option value="07">Julho</option> <option value="08">Agosto</option> <option value="09">Setembro</option> <option value="10">Outubro</option> <option value="11">Novembro</option> <option value="12">Dezembro</option> </select> Apagar todo o esqueleto inicial e acrescentar o código ao lado. Nele foi adicionado um botão com configuração "liga/desliga" do Bootstrap ("collapse"). Ao ser clicado ele deixará visível o formulário. O formulário possui uma lista de seleção de meses que está vinculado a variável "mes" do TypeScript. O resultado da consulta aparecerá apenas quando o formulário for enviado para o servidor. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 27/34 <button class="btn btn-primary mx-2" type="submit"> Consulta </button> </div> </form> </div> <br> <div style="background-color: lightgray;" [hidden]="!enviado" class="shadow"> <b>Faturas:</b><br> <ol> <div *ngFor="let fatura of lista_foradoprazo" > <li> {{ fatura.empresa }} - Data pagto em: <span style="color: blue;"> {{ fatura.dt_pagto | date : 'dd/MMM/yyyy' }} </span> e Data de vencto em: <span style="color: blue;">{{ fatura.dt_vencto | date : 'dd/MMM/yyyy' }} </span> </li> </div> </ol> <button class="btn btn-dark btn-sm ml-2" (click)="enviado=false">Desliga</button> </div> </div> b) "fat-foradoprazo.component.ts" import { Component, OnInit } from '@angular/core'; import { HttpClient } from "@angular/common/http"; @Component({ selector: 'app-fat-foradoprazo', templateUrl: './fat-foradoprazo.component.html', styleUrls: ['./fat-foradoprazo.component.css'] }) export class FatForadoprazoComponent implements OnInit { constructor( private http: HttpClient) { } mes: string = ''; enviado = false; lista_foradoprazo: any = []; envia() { this.enviado = true; const campos = "mes="+this.mes ; const url ='http://localhost:3000/foradoprazo'; O código TypeScript vai criar uma lista "lista_foradoprazo" com o resultado da consulta no servidor. É enviado a seleção do mês pelo usuário usando o método POST do HTTP. Ao receber a resposta por meio da função anônima, a lista é atualizada com o resultado em formato JSON. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 28/34 this.http.post(url , campos ).subscribe( (resposta) => { this.lista_foradoprazo = resposta; console.log( this.lista_foradoprazo ); }, (erro) => console.log(erro) ); } } Ao executar a aplicação, temos o resultado na tela, como a sequência apresentada no Quadro 18. Quadro 18 – Sequência da visualização dos dados do componente Ao clicar no botão “Lista faturas pagas fora do prazo…”, o formulário aparecerá com a lista de meses e o botão para enviar a consulta ao servidor. Ao receber o resultado do servidor, uma lista com as empresas que tiveram suas faturas pagas fora do prazo aparecerá com destaque para o dia de pagamento e o dia de vencimento, formatados com o filtro do Angular. A nova aplicação reúne os principais tópicos vistos sobre o framework Angular, que podem servir como base para uma aplicação real, com componentes, acesso a um servidor HTTP, consulta a base de dados e formatação visual usando Bootstrap. Mesmo com todos esses conceitos aplicados, em aplicações maiores e mais sofisticadas, muitos outros conhecimentos devem ser adicionados e muitos dos que foram vistos nestas aulas devem ser aprofundados. Tanto o framework Angular quanto o Bootstrap, assim como a linguagem JavaScript e ambiente Node.js têm diversos pontos a serem estudados e implantados, fazendo com que uma aplicação adquira a sofisticação de um produto comercial. Mas, para conseguir evoluir, é preciso praticar bastante os conceitos vistos nestas aulas, até dominar o entendimento e o fluxo do desenvolvimento. TEMA 5 – INSTALANDO UM APLICATIVO ANGULAR 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 29/34 Neste último tópico, vamos verificar como podemos instalar nossa aplicação SPA Angular em um dispositivo móvel. Mesmo podendo acessar nossos exemplos em navegadores instalados em qualquer tipo de dispositivo, um aplicativo é melhor integrado ao sistema operacional e proporciona uma melhor experiência de uso para o usuário. Os procedimentos para transformar nossa aplicação SPA Angular em um aplicativo PWA envolvem a adoção de parâmetros e configurações que são facilitadas pelo utilitário “ng”, e para isso basta instalar “ng add @angular/pwa” (Getting..., [S.d.]). 5.1 DISTRIBUINDO A APLICAÇÃO Com o ajuste finalizado, devemos preparar a aplicação para uso em produção, o que envolve a compilação e empacotamento de todos os arquivos necessários para distribuição.Esse passo seria feito independentemente de conversão para PWA e serve também para finalizar a aplicação Angular: “ng build --prod”. No contexto do nosso último projeto, a pasta “dist/app-fat” será criada e todos os arquivos necessários estarão armazenados lá. Basta incluir esses poucos arquivos num servidor HTTP e nossa aplicação pode ser liberada. No caso do PWA, o servidor de teste do Angular não funciona e por esse motivo teremos que utilizar outra opção. Para facilitar, temos o pacote “http-server” no Node.js, que pode ser utilizado (Getting..., 2021). Basta instalar com “npm install http-server” e executar “http-server -p 8080 -c-1 dist/app-fat” na pasta do projeto. 5.2 DESKTOP Utilizando o navegador Chrome, ao digitar a URL para o “http://localhost:8080”, teremos o acesso a aplicação como vimos anteriormente. Mas, agora que nossa aplicação Angular foi adaptada para o PWA, vamos ter adicionalmente uma opção de instalação (ver Figura 7). Figura 7 – Navegador Chrome com opção de instalação de aplicação PWA 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 30/34 Na Figura 8, um exemplo de nossa aplicação instalada como um aplicativo desktop em um Linux Mint, que é o mesmo procedimento que pode ser seguido no sistema operacional Windows. Figura 8 – Aplicação desktop instalada via navegador Essa aplicação, a partir da instalação, poderá ser vista nos menus de aplicativos do sistema operacional. 5.3 INSTALAÇÃO EM SMARTPHONE Quando testado no ambiente de teste local, as configurações feitas no Node.js para acesso remoto ao banco de dados Mysql estavam associadas ao endereço local (localhost) nas URLs. O uso de endereços privados na rede local permitia que a aplicação Angular fosse acessada pelo navegador do dispositivo móvel (ver Quadro 19, com as telas de acesso no dispositivo Android). Como foi utilizado o framework Bootstrap, as informações ficam adaptadas ao tamanho da tela do dispositivo. Quadro 19 – Telas de acesso a aplicação angular com navegador do sistema Android 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 31/34 Contudo, considerando que o PWA é um aplicativo com forte integração com o sistema operacional, algumas características de segurança foram implementadas. Ele só será instalado nos dispositivos com uma conexão segura ("HTTPS"). Em ambiente de teste, com o sistema sendo acessado localmente (com endereço localhost ou 127.0.0.1), o PWA pode ser acionado. Mas no caso de acesso remoto, precisamos de um servidor com conexão criptografada (HTTPS). Uma opção para testarmos nossa aplicação PWA no smartphone é o uso do ambiente GitHub (site de hospedagem de código usando o aplicativo “git”), que possui uma opção de consulta de páginas com HTTPS. Na Figura 9, temos um repositório chamado webang para hospedar nosso código e, com a sequência de comandos abaixo, temos a publicação do código no GitHub: a. “git add .” – inclui todas as modificações no espaço de trabalho do “git”; b. “git commit -m 'pwa'” – autoriza o armazenamento das modificações; c. “git remote add origin https://github.com/Yankocosta/webang.git” – inclui o repositório como armazenamento remoto do git; d. “git push -u origin main” – envia o código para o repositório remoto. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 32/34 Figura 9 – Repositório webang criado no site GitHub Com o comando “npx gh-pages -d dist/app-fat/” executado na pasta do projeto, criamos uma página de acesso ao projeto, que poderá ser acessada com “https://yankocosta.github.io/webang”. Recompilando nosso código para hospedagem no GitHub com o comando “ng build --prod -- base-href=/webang/”, enviando novamente para o repositório com “git commit -a -m "pwa2" e criando a página de distribuição com “npx gh-pages -d dist/app-fat/”, temos nosso aplicativo sendo acessado com HTTPS e poderá ser instalado no Android, como mostra o Quadro 20. Quadro 20 – Telas do aplicativo PWA no Android a) Instalação b) Tela inicial c) Listagem de aplicativos 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 33/34 Com o uso do mecanismo do PWA, temos um aplicativo que pode ser acessado diretamente dentro do ambiente do dispositivo móvel ou do desktop como se fosse uma aplicação independente. Os cuidados que devem ser tomados com uma aplicação que faz acesso remoto envolvem também os endereços de rede que serão usados nos acessos e nas liberações de restrição tanto na aplicação PWA quanto na aplicação backend no servidor e que podem se tornar mais complexos, dependendo da sofisticação da infraestrutura envolvida. Em alguns casos, firewalls, containers, virtualização e balanceamento de carga exigem um maior cuidado nas configurações e podem impactar na comunicação entre os sistemas envolvidos. FINALIZANDO Apesar de um maior peso na questão didática ao criar os exemplos, os tópicos e códigos utilizados, assim como algumas funcionalidades, foram desenvolvidos de forma a também servirem como ponto de referência para sistemas a serem desenvolvidos com Angular. Contudo, para o desenvolvimento de sistemas completos e com mais funcionalidades, outras características dos tópicos apresentados nas aulas devem ser aprofundadas. Com o entendimento proporcionado pelos fundamentos, teorias e exemplos, a expectativa é de que esse progresso seja mais tranquilo e rápido. Nesta aula, tivemos a implantação de uma apresentação ao usuário mais automatizada com o uso dos mecanismos de template do Angular. Com o uso de atributos de repetição e decisão, pudemos deixar nosso HTML mais flexível ao volume de dados que podem ser recebidos na aplicação. Tivemos nosso ambiente de testes evoluído com a criação de servidor HTTP e banco de dados, que possibilitaram os testes de comunicação entre cliente e servidor. Adicionamos um formulário para capturar as necessidades do usuário e estruturamos os procedimentos de envio e recepção de dados. A cada passo, fomos acrescentando alguma nova configuração, até juntarmos vários tópicos numa aplicação que permitisse testar a integração entre os conceitos. Ao final, pudemos testar a integração de nossa aplicação ao sistema operacional do dispositivo cliente, usando a adaptação do sistema SPA Angular para um PWA. 10/09/2021 16:13 UNINTER - FERRAMENTAS DE DESENVOLVIMENTO WEB https://conteudosdigitais.uninter.com/libraries/newrota/?c=/gradNova/2021/analiseDesenvSistemas/ferramentasDesenvWeb/a6 34/34 REFERÊNCIAS DEITEL, P. J.; DEITEL, H. M. Ajax, rich internet applications e desenvolvimento web para programadores. São Paulo: Pearson Prentice Hall, 2009. GETTING started with service workers. Angular, [S.d.]. Disponível em: <https://angular.io/guide/service-worker-getting-started>. Acesso em: 28 mar. 2021. TEMPLATE syntax. Angular, [S.d.]. Disponível em: <https://angular.io/guide/template-syntax>. Acesso em: 28 mar. 2021.
Compartilhar