|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 4 months ago | |
| assignment.md | 4 months ago | |
README.md
Construir uma App Bancária Parte 3: Métodos de Obtenção e Utilização de Dados
Pense no computador da Enterprise em Star Trek – quando o Capitão Picard pede o estado da nave, a informação aparece instantaneamente sem que toda a interface desligue e se reconstrua. Esse fluxo contínuo de informações é exatamente o que estamos a construir aqui com a obtenção dinâmica de dados.
Neste momento, a sua app bancária é como um jornal impresso – informativa mas estática. Vamos transformá-la em algo mais como o controlo de missão da NASA, onde os dados fluem continuamente e são atualizados em tempo real sem interromper o fluxo de trabalho do utilizador.
Vai aprender a comunicar com servidores de forma assíncrona, lidar com dados que chegam em momentos diferentes e transformar informação bruta em algo significativo para os seus utilizadores. Esta é a diferença entre uma demo e um software pronto para produção.
⚡ O Que Pode Fazer Nos Próximos 5 Minutos
Caminho Rápido para Desenvolvedores Ocupados
flowchart LR
A[⚡ 5 minutos] --> B[Configurar servidor API]
B --> C[Testar fetch com curl]
C --> D[Criar função de login]
D --> E[Ver dados em ação]
- Minutos 1-2: Inicie o seu servidor API (
cd api && npm start) e teste a ligação - Minuto 3: Crie uma função básica
getAccount()usando fetch - Minuto 4: Ligue o formulário de login com
action="javascript:login()" - Minuto 5: Teste o login e veja os dados da conta aparecerem na consola
Comandos de Teste Rápido:
# Verificar se a API está a funcionar
curl http://localhost:5000/api
# Testar a obtenção de dados da conta
curl http://localhost:5000/api/accounts/test
Porquê Isto é Importante: Em 5 minutos, verá a magia da obtenção de dados assíncrona que alimenta todas as aplicações web modernas. Esta é a base que torna as apps responsivas e dinâmicas.
🗺️ O Seu Percurso de Aprendizagem em Aplicações Web Baseadas em Dados
journey
title De Páginas Estáticas a Aplicações Dinâmicas
section Compreender a Evolução
Recarregamentos tradicionais de página: 3: You
Descobrir benefícios do AJAX/SPA: 5: You
Dominar padrões Fetch API: 7: You
section Construir Autenticação
Criar funções de login: 4: You
Lidar com operações assíncronas: 6: You
Gerir sessões de utilizador: 8: You
section Atualizações Dinâmicas da IU
Aprender manipulação do DOM: 5: You
Construir exibições de transações: 7: You
Criar painéis responsivos: 9: You
section Padrões Profissionais
Renderização baseada em templates: 6: You
Estratégias de tratamento de erros: 7: You
Otimização de desempenho: 8: You
Destino do Seu Percurso: No final desta lição, vai entender como as aplicações web modernas obtêm, processam e exibem dados dinamicamente, criando as experiências de utilizador fluídas que esperamos de aplicações profissionais.
Questionário Pré-Aula
Pré-requisitos
Antes de mergulhar na obtenção de dados, tenha estes componentes prontos:
- Lição Anterior: Complete o Formulário de Login e Registo – vamos construir sobre esta base
- Servidor Local: Instale Node.js e execute o servidor API para fornecer dados da conta
- Ligação à API: Teste a ligação ao seu servidor com este comando:
curl http://localhost:5000/api
# Resposta esperada: "API do Banco v1.0.0"
Este teste rápido assegura que todos os componentes estão a comunicar corretamente:
- Verifica que o Node.js está a funcionar corretamente no seu sistema
- Confirma que o seu servidor API está ativo e a responder
- Valida que a sua app pode alcançar o servidor (como verificar contacto rádio antes de uma missão)
🧠 Visão Geral do Ecossistema de Gestão de Dados
mindmap
root((Gestão de Dados))
Authentication Flow
Processo de Login
Validação de Formulário
Verificação de Credenciais
Gestão de Sessão
Estado do Utilizador
Objeto Global da Conta
Guardas de Navegação
Gestão de Erros
API Communication
Padrões de Requisição
Requisições GET
Requisições POST
Respostas de Erro
Formatos de Dados
Processamento JSON
Codificação URL
Análise de Resposta
Dynamic UI Updates
Manipulação do DOM
Atualizações Seguras de Texto
Criação de Elementos
Clonagem de Templates
Experiência do Utilizador
Atualizações em Tempo Real
Mensagens de Erro
Estados de Carregamento
Security Considerations
Prevenção XSS
Uso de textContent
Sanitização de Entrada
Criação Segura de HTML
Gestão de CORS
Requisições Cross-Origin
Configuração de Cabeçalhos
Configuração de Desenvolvimento
Princípio Fundamental: Aplicações web modernas são sistemas de orquestração de dados – coordenam interfaces de utilizador, APIs de servidor e modelos de segurança do navegador para criar experiências fluidas e responsivas.
Compreender a Obtenção de Dados em Aplicações Web Modernas
A forma como as aplicações web lidam com dados evoluiu dramaticamente nas últimas duas décadas. Compreender esta evolução ajudará a apreciar porque técnicas modernas como AJAX e a API Fetch são tão poderosas e por que se tornaram ferramentas essenciais para os desenvolvedores web.
Vamos explorar como os sites tradicionais funcionavam comparados com as aplicações dinâmicas e responsivas que construímos hoje.
Aplicações Tradicionais de Múltiplas Páginas (MPA)
Nos primórdios da web, cada clique era como mudar de canal numa televisão antiga – o ecrã ficava em branco e depois sintonizava lentamente o novo conteúdo. Esta era a realidade das primeiras aplicações web, onde cada interação significava reconstruir a página inteira do zero.
sequenceDiagram
participant User
participant Browser
participant Server
User->>Browser: Clica no link ou submete formulário
Browser->>Server: Requisita nova página HTML
Note over Browser: A página fica em branco
Server->>Browser: Devolve página HTML completa
Browser->>User: Mostra nova página (flash/recarregamento)
Porque este método parecia pesado:
- Cada clique implicava reconstruir a página inteira do zero
- Os utilizadores eram interrompidos no meio do pensamento por aqueles flashes irritantes de página
- A ligação à internet trabalhava em excesso a descarregar o mesmo cabeçalho e rodapé repetidamente
- As apps pareciam mais um arquivo de gavetas para clicar do que software a usar
Aplicações Modernas de Página Única (SPA)
AJAX (JavaScript assíncrono e XML) mudou este paradigma completamente. Como o design modular da Estação Espacial Internacional, onde os astronautas podem substituir componentes individuais sem reconstruir toda a estrutura, AJAX permite-nos atualizar partes específicas de uma página sem recarregar tudo. Apesar do nome mencionar XML, hoje em dia usamos principalmente JSON, mas o princípio central mantém-se: atualizar apenas o que precisa de mudar.
sequenceDiagram
participant User
participant Browser
participant JavaScript
participant Server
User->>Browser: Interage com a página
Browser->>JavaScript: Activa o manipulador de eventos
JavaScript->>Server: Busca apenas os dados necessários
Server->>JavaScript: Devolve dados JSON
JavaScript->>Browser: Actualiza elementos específicos da página
Browser->>User: Mostra conteúdo actualizado (sem recarregar)
Porque é que as SPAs parecem muito melhores:
- Só as partes que realmente mudaram são atualizadas (inteligente, certo?)
- Sem interrupções bruscas – o utilizador mantém o seu fluxo
- Menos dados a viajar, significado carregamentos mais rápidos
- Tudo parece rápido e responsivo, como as apps no seu telemóvel
A Evolução para a API Fetch Moderna
Os navegadores modernos fornecem a Fetch API, que substitui o antigo XMLHttpRequest. Como a diferença entre operar um telégrafo e usar email, a API Fetch usa promessas para um código assíncrono mais limpo e manipula JSON naturalmente.
| Característica | XMLHttpRequest | Fetch API |
|---|---|---|
| Sintaxe | Complexa baseada em callbacks | Limpa baseada em promessas |
| Manipulação de JSON | Análise manual necessária | Método .json() incorporado |
| Gestão de Erros | Informações limitadas | Detalhes completos de erros |
| Suporte Moderno | Compatibilidade legado | Promessas ES6+ e async/await |
💡 Compatibilidade dos Navegadores: Boas notícias – a Fetch API funciona em todos os navegadores modernos! Se tiver curiosidade sobre versões específicas, caniuse.com tem a história completa de compatibilidade.
Conclusão:
- Funciona bem no Chrome, Firefox, Safari e Edge (basicamente em todo o lado onde os utilizadores estão)
- Apenas o Internet Explorer precisa de ajuda extra (e honestamente, está na hora de deixar o IE para trás)
- Prepara-o perfeitamente para os padrões elegantes async/await que usaremos mais tarde
Implementar Login de Utilizador e Recuperação de Dados
Agora vamos implementar o sistema de login que transforma a sua app bancária de uma exibição estática numa aplicação funcional. Como os protocolos de autenticação usados em instalações militares seguras, vamos verificar as credenciais do utilizador e depois fornecer acesso aos seus dados específicos.
Vamos construir isso incrementalmente, começando com a autenticação básica e depois adicionando a capacidade de obter dados.
Passo 1: Criar a Fundação da Função de Login
Abra o seu ficheiro app.js e adicione uma nova função login. Esta vai tratar do processo de autenticação:
async function login() {
const loginForm = document.getElementById('loginForm');
const user = loginForm.user.value;
}
Vamos detalhar este código:
- A palavra-chave
async? Está a dizer ao JavaScript "ei, esta função pode precisar de esperar por coisas" - Estamos a obter o nosso formulário da página (nada de especial, apenas a encontrar pelo ID)
- Depois extraímos o que o utilizador digitou como nome de utilizador
- Aqui está um truque: pode aceder a qualquer input do formulário pelo seu atributo
name– não precisa de chamadas extras getElementById!
💡 Padrão de Acesso a Formulários: Cada controlo de formulário pode ser acedido pelo seu nome (definido em HTML usando o atributo
name) como uma propriedade do elemento de formulário. Isto fornece uma forma limpa e legível de obter os dados do formulário.
Passo 2: Criar a Função de Obtenção de Dados da Conta
A seguir, vamos criar uma função dedicada para obter os dados da conta do servidor. Isto segue o mesmo padrão da sua função de registo mas foca-se na obtenção de dados:
async function getAccount(user) {
try {
const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user));
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}
Isto é o que este código faz:
- Usa a moderna API
fetchpara solicitar dados de forma assíncrona - Constrói uma URL para uma requisição GET com o parâmetro do nome de utilizador
- Aplica
encodeURIComponent()para tratar caracteres especiais nas URLs em segurança - Converte a resposta para o formato JSON para facilitar a manipulação dos dados
- Lida com erros de forma elegante, retornando um objeto de erro em vez de falhar
⚠️ Nota de Segurança: A função
encodeURIComponent()trata caracteres especiais em URLs. Como os sistemas de codificação usados em comunicações navais, garante que a sua mensagem chega exatamente como pretendida, prevenindo que caracteres como "#" ou "&" sejam mal interpretados.
Porque isto é importante:
- Prevém que caracteres especiais partam URLs
- Protege contra ataques de manipulação de URL
- Garante que o seu servidor recebe os dados pretendidos
- Segue práticas seguras de programação
Compreender Requisições HTTP GET
Aqui está algo que pode surpreendê-lo: quando usa fetch sem opções adicionais, ele cria automaticamente uma requisição GET. Isto é perfeito para o que estamos a fazer – pedir ao servidor "ei, posso ver os dados da conta deste utilizador?"
Pense nas requisições GET como pedir educadamente emprestado um livro na biblioteca – está a solicitar ver algo que já existe. Requisições POST (que usamos para registo) são mais como submeter um novo livro para adicionar à coleção.
| Requisição GET | Requisição POST |
|---|---|
| Objetivo | Recuperar dados existentes |
| Parâmetros | Na URL / query string |
| Cache | Pode ser guardada em cache pelos navegadores |
| Segurança | Visível na URL/logs |
sequenceDiagram
participant B as Browser
participant S as Server
Note over B,S: Pedido GET (Recuperação de Dados)
B->>S: GET /api/accounts/test
S-->>B: 200 OK + Dados da Conta
Note over B,S: Pedido POST (Submissão de Dados)
B->>S: POST /api/accounts + Novos Dados da Conta
S-->>B: 201 Created + Confirmação
Note over B,S: Tratamento de Erros
B->>S: GET /api/accounts/nonexistent
S-->>B: 404 Not Found + Mensagem de Erro
Passo 3: Juntar Tudo
Agora a parte satisfatória – vamos ligar a função de obtenção da conta ao processo de login. É aqui que tudo se encaixa:
async function login() {
const loginForm = document.getElementById('loginForm');
const user = loginForm.user.value;
const data = await getAccount(user);
if (data.error) {
return console.log('loginError', data.error);
}
account = data;
navigate('/dashboard');
}
Esta função segue uma sequência clara:
- Extrai o nome do utilizador do input do formulário
- Solicita os dados da conta do utilizador ao servidor
- Trata quaisquer erros que ocorram durante o processo
- Armazena os dados da conta e navega para o dashboard em caso de sucesso
🎯 Padrão Async/Await: Como
getAccounté uma função assíncrona, usamos a palavra-chaveawaitpara pausar a execução até o servidor responder. Isto previne que o código continue com dados indefinidos.
Passo 4: Criar um Local para os Seus Dados
A sua app precisa de um local para guardar a informação da conta depois de carregada. Pense nisto como a memória de curto prazo da sua app – um lugar para manter os dados do utilizador atual à mão. Adicione esta linha no topo do seu ficheiro app.js:
// Isto contém os dados da conta do utilizador atual
let account = null;
Porque precisamos disto:
- Mantém os dados da conta acessíveis de qualquer parte da sua app
- Começar com
nullsignifica "ninguém está logado ainda" - Atualiza-se quando alguém faz login ou regista com sucesso
- Age como uma fonte única de verdade – nenhuma confusão sobre quem está logado
Passo 5: Ligar o Seu Formulário
Agora vamos ligar a sua nova função de login ao formulário HTML. Atualize a tag do seu formulário assim:
<form id="loginForm" action="javascript:login()">
<!-- Your existing form inputs -->
</form>
O que esta pequena alteração faz:
- Impede o formulário de fazer o seu comportamento padrão de "recarregar a página inteira"
- Chama a sua função JavaScript personalizada em vez disso
- Mantém tudo suave e como uma aplicação de página única
- Dá-lhe controlo completo sobre o que acontece quando os utilizadores clicam em "Login"
Passo 6: Melhorar a Sua Função de Registo
Para manter a consistência, atualize a sua função register para também guardar os dados da conta e navegar para o dashboard:
// Adicione estas linhas no final da sua função de registo
account = result;
navigate('/dashboard');
Esta melhoria proporciona:
- Transição fluida do registo para o dashboard
- Experiência consistente para o utilizador entre fluxos de login e registo
- Acesso imediato aos dados da conta após registo bem-sucedido
Testar a Sua Implementação
flowchart TD
A[Utilizador insere credenciais] --> B[Função de login chamada]
B --> C[Obter dados da conta do servidor]
C --> D{Dados recebidos com sucesso?}
D -->|Sim| E[Guardar dados da conta globalmente]
D -->|Não| F[Exibir mensagem de erro]
E --> G[Navegar para o painel]
F --> H[Utilizador permanece na página de login]
Hora de experimentar:
- Crie uma nova conta para garantir que tudo funciona
- Tente fazer login com essas mesmas credenciais
- Espie a consola do seu navegador (F12) se algo parecer estranho
- Certifique-se que chega ao dashboard após um login bem-sucedido
Se algo não estiver a funcionar, não entre em pânico! A maioria dos problemas são correções simples como erros de digitação ou esquecer de arrancar o servidor API.
Uma Palavra Rápida Sobre a Magia Cross-Origin
Pode estar a perguntar-se: "Como é que a minha app web está a falar com este servidor API se estão a correr em portas diferentes?" Ótima pergunta! Isto toca num ponto que todos os desenvolvedores web acabam por encontrar.
🔒 Segurança Cross-Origin: Os navegadores aplicam uma "política de mesma origem" para prevenir comunicações não autorizadas entre domínios diferentes. Como o sistema de controlo num posto de segurança, verificam que a comunicação é autorizada antes de permitir a transferência de dados.
Na nossa configuração:
- A sua app web corre em
localhost:3000(servidor de desenvolvimento) - O seu servidor API corre em
localhost:5000(servidor backend) - O servidor API inclui headers CORS que autorizam explicitamente a comunicação da sua app web
Esta configuração espelha o ambiente real de desenvolvimento onde as aplicações frontend e backend tipicamente correm em servidores separados.
📚 Saiba Mais: Aprofunde APIs e obtenção de dados com este módulo abrangente da Microsoft Learn sobre APIs.
Dar Vida aos Seus Dados em HTML
Agora vamos tornar os dados obtidos visíveis aos utilizadores através da manipulação do DOM. Tal como o processo de revelar fotografias num laboratório, estamos a pegar em dados invisíveis e a transformá-los em algo que os utilizadores podem ver e interagir. A manipulação do DOM é a técnica que transforma páginas web estáticas em aplicações dinâmicas que atualizam o seu conteúdo com base nas interações do utilizador e nas respostas do servidor.
Escolher a Ferramenta Certa para o Trabalho
Quando se trata de atualizar o seu HTML com JavaScript, tem várias opções. Pense nelas como diferentes ferramentas numa caixa de ferramentas – cada uma perfeita para trabalhos específicos:
| Método | Em que é boa | Quando usar | Nível de segurança |
|---|---|---|---|
textContent |
Exibir dados do utilizador de forma segura | Sempre que mostrar texto | ✅ À prova de bala |
createElement() + append() |
Construir layouts complexos | Criar secções/listas novas | ✅ À prova de bala |
innerHTML |
Definir conteúdo HTML | ⚠️ Tente evitar este | ❌ Negócio arriscado |
A Forma Segura de Mostrar Texto: textContent
A propriedade textContent é a sua melhor amiga quando mostra dados do utilizador. É como ter um segurança na sua página web – nada de prejudicial passa:
// A forma segura e fiável de atualizar texto
const balanceElement = document.getElementById('balance');
balanceElement.textContent = account.balance;
Benefícios do textContent:
- Trata tudo como texto simples (evita a execução de scripts)
- Limpa automaticamente o conteúdo existente
- Eficiente para atualizações simples de texto
- Proporciona segurança incorporada contra conteúdos maliciosos
Criar Elementos HTML Dinâmicos
Para conteúdos mais complexos, combine document.createElement() com o método append():
// Maneira segura de criar novos elementos
const transactionItem = document.createElement('div');
transactionItem.className = 'transaction-item';
transactionItem.textContent = `${transaction.date}: ${transaction.description}`;
container.append(transactionItem);
Compreender esta abordagem:
- Cria novos elementos DOM programaticamente
- Mantém pleno controlo sobre os atributos e conteúdo dos elementos
- Permite estruturas complexas e aninhadas de elementos
- Preserva a segurança, separando estrutura do conteúdo
⚠️ Consideração de Segurança: Embora
innerHTMLapareça em muitos tutoriais, pode executar scripts embutidos. Tal como os protocolos de segurança no CERN que impedem a execução não autorizada de código, usartextContentecreateElementoferece alternativas mais seguras.
Riscos do innerHTML:
- Executa quaisquer tags
<script>nos dados do utilizador - Vulnerável a ataques de injeção de código
- Cria potenciais vulnerabilidades de segurança
- As alternativas mais seguras que usamos fornecem funcionalidades equivalentes
Tornar os Erros Amigáveis para o Utilizador
Atualmente, os erros de login aparecem apenas na consola do navegador, que é invisível para os utilizadores. Tal como a diferença entre os diagnósticos internos de um piloto e o sistema de informação para passageiros, precisamos de comunicar informações importantes pelo canal apropriado.
Implementar mensagens de erro visíveis oferece aos utilizadores feedback imediato sobre o que correu mal e como proceder.
Passo 1: Adicionar um Espaço para Mensagens de Erro
Primeiro, vamos dar às mensagens de erro um lugar no seu HTML. Adicione isto mesmo antes do seu botão de login para que os utilizadores o vejam naturalmente:
<!-- This is where error messages will appear -->
<div id="loginError" role="alert"></div>
<button>Login</button>
O que está a acontecer aqui:
- Estamos a criar um contentor vazio que fica invisível até ser necessário
- Está posicionado onde os utilizadores naturalmente olham depois de clicar em "Login"
- Esse
role="alert"é um toque especial para leitores de ecrã – diz à tecnologia assistiva "olha, isto é importante!" - O
idúnico dá ao nosso JavaScript um alvo fácil
Passo 2: Criar uma Função Utilitária Útil
Vamos criar uma pequena função utilitária que pode atualizar o texto de qualquer elemento. Esta é daquelas funções "escreve uma vez, usa em todo o lado" que lhe vai poupar tempo:
function updateElement(id, text) {
const element = document.getElementById(id);
element.textContent = text;
}
Benefícios da função:
- Interface simples que só precisa do ID do elemento e do texto
- Localiza e atualiza elementos DOM de forma segura
- Padrão reutilizável que reduz a duplicação de código
- Mantém comportamento consistente de atualização na aplicação
Passo 3: Mostrar Erros Onde os Utilizadores os Podem Ver
Agora vamos substituir aquela mensagem oculta da consola por algo que os utilizadores possam realmente ver. Atualize a sua função de login:
// Em vez de apenas registar no console, mostre ao utilizador o que está errado
if (data.error) {
return updateElement('loginError', data.error);
}
Esta pequena mudança faz uma grande diferença:
- As mensagens de erro aparecem exatamente onde os utilizadores estão a olhar
- Chega de falhas silenciosas e misteriosas
- Os utilizadores recebem feedback imediato e acionável
- A sua app começa a parecer profissional e atenciosa
Agora, quando testar com uma conta inválida, verá uma mensagem de erro útil diretamente na página!
Passo 4: Ser Inclusivo com Acessibilidade
Aqui está algo fixe sobre esse role="alert" que adicionámos antes – não é só decoração! Este pequeno atributo cria o que se chama uma Região Live que anuncia imediatamente as alterações aos leitores de ecrã:
<div id="loginError" role="alert"></div>
Porque é que isto importa:
- Utilizadores de leitores de ecrã ouvem a mensagem de erro assim que ela aparece
- Todos recebem a mesma informação importante, independentemente da forma como navegam
- É uma forma simples de fazer a sua app funcionar para mais pessoas
- Demonstra que se importa em criar experiências inclusivas
Pequenos pormenores como este distinguem bons programadores de excelentes!
🎯 Verificação Pedagógica: Padrões de Autenticação
Pausa e Refletir: Acaba de implementar um fluxo completo de autenticação. Este é um padrão fundamental no desenvolvimento web.
Autoavaliação Rápida:
- Consegue explicar porque usamos async/await para chamadas à API?
- O que aconteceria se esquecêssemos a função
encodeURIComponent()? - Como é que o nosso tratamento de erros melhora a experiência do utilizador?
Conexão com o Mundo Real: Os padrões que aprendeu aqui (busca assíncrona de dados, tratamento de erros, feedback para o utilizador) são usados em todas as grandes aplicações web, desde plataformas de redes sociais até sites de comércio electrónico. Está a construir competências ao nível de produção!
Questão Desafio: Como poderia modificar este sistema de autenticação para lidar com múltiplos papéis de utilizador (cliente, administrador, operador)? Pense na estrutura de dados e nas alterações de UI necessárias.
Passo 5: Aplicar o Mesmo Padrão ao Registo
Para manter a consistência, implemente o mesmo tratamento de erros no seu formulário de registo:
- Adicione um elemento de exibição de erros ao seu HTML do registo:
<div id="registerError" role="alert"></div>
- Atualize a sua função de registo para usar o mesmo padrão de exibição de erros:
if (data.error) {
return updateElement('registerError', data.error);
}
Benefícios do tratamento consistente de erros:
- Proporciona uma experiência de utilizador uniforme em todos os formulários
- Reduz a carga cognitiva usando padrões familiares
- Simplifica a manutenção com código reutilizável
- Garante que os padrões de acessibilidade são cumpridos em toda a aplicação
Criar o Seu Painel de Controlo Dinâmico
Agora vamos transformar o seu painel de controlo estático numa interface dinâmica que exibe dados reais da conta. Tal como a diferença entre um horário de voos impresso e os quadros de partidas em tempo real nos aeroportos, estamos a passar de informação estática para exibições responsivas e em tempo real.
Usando as técnicas de manipulação do DOM que aprendeu, vamos criar um painel que se atualiza automaticamente com a informação atual da conta.
Conhecer os Seus Dados
Antes de começar a construir, vejamos que tipo de dados o seu servidor envia. Quando alguém faz login com sucesso, aqui está o tesouro de informações com que vai trabalhar:
{
"user": "test",
"currency": "$",
"description": "Test account",
"balance": 75,
"transactions": [
{ "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
{ "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
{ "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
]
}
Esta estrutura de dados fornece:
user: Perfeito para personalizar a experiência ("Bem-vinda de volta, Sara!")currency: Garante que mostramos valores monetários corretamentedescription: Um nome amigável para a contabalance: O saldo atual, muito importantetransactions: O histórico completo de transações com todos os detalhes
Tudo o que precisa para construir um painel bancário profissional!
flowchart TD
A[Início de Sessão do Utilizador] --> B[Obter Dados da Conta]
B --> C{Dados Válidos?}
C -->|Sim| D[Armazenar em Variável Global]
C -->|Não| E[Mostrar Mensagem de Erro]
D --> F[Navegar para o Painel]
F --> G[Atualizar Elementos da IU]
G --> H[Exibir Saldo]
G --> I[Mostrar Descrição]
G --> J[Renderizar Transações]
J --> K[Criar Linhas da Tabela]
K --> L[Formatação de Moeda]
L --> M[Utilizador Vê Dados em Tempo Real]
💡 Dica Profissional: Quer ver o seu painel em ação imediatamente? Use o nome de utilizador
testquando fizer login – vem pré-carregado com dados de exemplo para ver tudo a funcionar sem ter que criar transações primeiro.
Porque a conta de teste é útil:
- Vem com dados de exemplo realistas já carregados
- Perfeita para ver como as transações são apresentadas
- Excelente para testar as funcionalidades do seu painel
- Poupa-lhe o trabalho de criar dados de teste manualmente
Criar os Elementos para Exibição do Painel
Vamos construir a interface do seu painel passo a passo, começando pela informação do resumo da conta e depois passando para funcionalidades mais complexas como listas de transações.
Passo 1: Atualizar a Estrutura HTML
Primeiro, substitua a secção estática do "Saldo" por elementos de espaço reservado dinâmicos que o seu JavaScript pode preencher:
<section>
Balance: <span id="balance"></span><span id="currency"></span>
</section>
De seguida, adicione uma secção para a descrição da conta. Como esta actua como um título para o conteúdo do painel, use HTML semântico:
<h2 id="description"></h2>
Compreender a estrutura HTML:
- Usa elementos
<span>separados para saldo e moeda para controlo individual - Aplica IDs únicos a cada elemento para ser alvo do JavaScript
- Segue o HTML semântico usando
<h2>para a descrição da conta - Cria uma hierarquia lógica para leitores de ecrã e SEO
✅ Perceção de Acessibilidade: A descrição da conta funciona como título do conteúdo do painel, por isso está marcada semanticamente como título. Saiba mais sobre como a estrutura de títulos impacta a acessibilidade. Consegue identificar outros elementos na sua página que poderiam beneficiar de tags de título?
Passo 2: Criar a Função de Atualização do Painel
Agora crie uma função que preenche o seu painel com dados reais da conta:
function updateDashboard() {
if (!account) {
return navigate('/login');
}
updateElement('description', account.description);
updateElement('balance', account.balance.toFixed(2));
updateElement('currency', account.currency);
}
Passo a passo, aqui está o que esta função faz:
- Valida que os dados da conta existem antes de avançar
- Redireciona utilizadores não autenticados de volta para a página de login
- Atualiza a descrição da conta usando a função reutilizável
updateElement - Formata o saldo para mostrar sempre duas casas decimais
- Exibe o símbolo da moeda apropriado
💰 Formatação Monetária: Esse método
toFixed(2)é uma dádiva! Garante que o saldo aparece sempre como dinheiro de verdade – "75.00" em vez de só "75". Os seus utilizadores vão apreciar ver a formatação familiar da moeda.
Passo 3: Garantir que o Painel se Atualiza
Para garantir que o seu painel se refresca com dados atuais sempre que alguém o visita, precisamos de ligar isto ao seu sistema de navegação. Se completou a tarefa da lição 1, isto deve parecer-lhe familiar. Se não, não se preocupe – aqui está o que precisa:
Adicione isto no fim da sua função updateRoute():
if (typeof route.init === 'function') {
route.init();
}
Depois atualize as suas rotas para incluir a inicialização do painel:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: updateDashboard }
};
O que esta configuração inteligente faz:
- Verifica se uma rota tem código especial de inicialização
- Executa esse código automaticamente quando a rota carrega
- Garante que o painel mostra sempre dados frescos e atualizados
- Mantém a lógica de navegação limpa e organizada
Testar o Seu Painel
Depois de implementar estas alterações, teste o seu painel:
- Faça login com uma conta de teste
- Verifique se é redirecionado para o painel
- Confirme que a descrição da conta, o saldo e a moeda aparecem corretamente
- Tente sair e entrar novamente para garantir que os dados se atualizam corretamente
O seu painel deverá agora mostrar informações dinâmicas da conta que se atualizam com base nos dados do utilizador autenticado!
Construir Listas de Transações Inteligentes com Templates
Em vez de criar manualmente HTML para cada transação, vamos usar templates para gerar formatação consistente automaticamente. Tal como os componentes padronizados usados na fabricação de naves espaciais, os templates asseguram que cada linha de transação segue a mesma estrutura e aparência.
Esta técnica escala eficientemente desde poucas até milhares de transações, mantendo desempenho e apresentação consistentes.
graph LR
A[Modelo HTML] --> B[Clone JavaScript]
B --> C[Preencher com Dados]
C --> D[Adicionar ao Fragmento]
D --> E[Inserção em Lote no DOM]
subgraph "Benefícios de Performance"
F[Actualização Única do DOM]
G[Formatação Consistente]
H[Padrão Reutilizável]
end
E --> F
E --> G
E --> H
flowchart LR
A[Dados da Transação] --> B[Modelo HTML]
B --> C[Clonar Modelo]
C --> D[Preencher com Dados]
D --> E[Adicionar ao DOM]
E --> F[Repetir para Cada Transação]
Passo 1: Criar o Template da Transação
Primeiro, adicione um template reutilizável para linhas de transação dentro do seu <body> HTML:
<template id="transaction">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
Compreender templates HTML:
- Define a estrutura para uma única linha de tabela
- Mantém-se invisível até ser clonada e preenchida com JavaScript
- Inclui três células para data, descrição e montante
- Fornece um padrão reutilizável para formatação consistente
Passo 2: Preparar a Tabela para Conteúdo Dinâmico
De seguida, adicione um id ao corpo da tabela para que o JavaScript possa selecioná-lo facilmente:
<tbody id="transactions"></tbody>
O que isto consegue:
- Cria um alvo claro para inserir as linhas de transação
- Separa a estrutura da tabela do conteúdo dinâmico
- Permite limpar e preencher facilmente os dados das transações
Passo 3: Construir a Função Fábrica de Linhas de Transação
Agora crie uma função que transforma dados de transações em elementos HTML:
function createTransactionRow(transaction) {
const template = document.getElementById('transaction');
const transactionRow = template.content.cloneNode(true);
const tr = transactionRow.querySelector('tr');
tr.children[0].textContent = transaction.date;
tr.children[1].textContent = transaction.object;
tr.children[2].textContent = transaction.amount.toFixed(2);
return transactionRow;
}
Análise desta função fábrica:
- Obtém o elemento template pelo ID
- Clona o conteúdo do template para manipulação segura
- Seleciona a linha da tabela dentro do conteúdo clonado
- Preenche cada célula com dados da transação
- Formata o montante para mostrar as casas decimais adequadas
- Devolve a linha completa pronta para inserção
Passo 4: Gerar Múltiplas Linhas de Transação de Forma Eficiente
Adicione este código na sua função updateDashboard() para mostrar todas as transações:
const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
const transactionRow = createTransactionRow(transaction);
transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);
Compreender esta abordagem eficiente:
- Cria um fragmento de documento para operações em lote no DOM
- Itera por todas as transações nos dados da conta
- Gera uma linha para cada transação usando a função fábrica
- Agrupa todas as linhas no fragmento antes de adicionar ao DOM
- Executa uma única atualização do DOM em vez de múltiplas inserções individuais
⚡ Otimização de Desempenho:
document.createDocumentFragment()funciona como o processo de montagem na Boeing – os componentes são preparados fora da linha principal, depois instalados como uma unidade completa. Esta abordagem de lote minimiza os reflows do DOM ao realizar uma única inserção em vez de múltiplas operações individuais.
Passo 5: Melhorar a Função de Atualização para Conteúdos Mistos
A sua função updateElement() atualmente só lida com conteúdo de texto. Atualize-a para trabalhar com texto e nós DOM:
function updateElement(id, textOrNode) {
const element = document.getElementById(id);
element.textContent = ''; // Remove todos os filhos
element.append(textOrNode);
}
Melhorias-chave nesta atualização:
- Limpa o conteúdo existente antes de adicionar novo conteúdo
- Aceita tanto cadeias de texto como nós DOM como parâmetros
- Utiliza o método
append()para maior flexibilidade - Mantém compatibilidade retroativa com o uso baseado em texto existente
Experimente o Seu Painel Dinâmico
Chegou o momento da verdade! Vamos ver o seu painel dinâmico em ação:
- Inicie sessão com a conta
test(tem dados de exemplo prontos para usar) - Navegue até ao seu painel
- Verifique se as linhas das transações aparecem com formatação correta
- Certifique-se de que datas, descrições e valores estão todos corretamente apresentados
Se tudo estiver a funcionar, deverá ver uma lista de transações totalmente funcional no seu painel! 🎉
O que conseguiu alcançar:
- Construiu um painel que dimensiona com qualquer quantidade de dados
- Criou templates reutilizáveis para formatação consistente
- Implementou técnicas eficientes de manipulação do DOM
- Desenvolveu uma funcionalidade comparável a aplicações bancárias em produção
Transformou com sucesso uma página web estática numa aplicação web dinâmica.
🎯 Verificação Pedagógica: Geração Dinâmica de Conteúdo
Compreensão da Arquitetura: Implementou uma pipeline complexa de dados para UI que espelha padrões usados em frameworks como React, Vue, e Angular.
Conceitos-Chave Dominados:
- Renderização baseada em templates: Criação de componentes de UI reutilizáveis
- Fragmentos de documento: Otimização do desempenho do DOM
- Manipulação segura do DOM: Prevenção de vulnerabilidades de segurança
- Transformação de dados: Conversão de dados do servidor para interfaces de utilizador
Ligação à Indústria: Estas técnicas formam a base dos frameworks modernos de frontend. O DOM virtual do React, o sistema de templates do Vue e a arquitetura de componentes do Angular constroem-se sobre estes conceitos fundamentais.
Questão de Reflexão: Como estenderia este sistema para lidar com atualizações em tempo real (como novas transações a aparecer automaticamente)? Considere WebSockets ou Eventos Enviados pelo Servidor.
📈 A Sua Linha Temporal de Domínio na Gestão de Dados
timeline
title Jornada de Desenvolvimento Orientado por Dados
section Construção da Base
Configuração e Teste da API
: Compreender a comunicação cliente-servidor
: Dominar o ciclo de pedido/resposta HTTP
: Aprender técnicas de depuração
section Domínio da Autenticação
Padrões de Funções Assíncronas
: Escrever código limpo com async/await
: Gerir promessas de forma eficaz
: Implementar limites de erro
Gestão de Sessão de Utilizador
: Criar padrões de estado global
: Construir guardas de navegação
: Conceber sistemas de feedback ao utilizador
section Desenvolvimento de UI Dinâmico
Manipulação Segura do DOM
: Prevenir vulnerabilidades XSS
: Usar textContent em vez de innerHTML
: Criar interfaces acessíveis
Sistemas de Templates
: Construir componentes UI reutilizáveis
: Otimizar desempenho com fragmentos
: Escalar para lidar com grandes conjuntos de dados
section Padrões Profissionais
Código Pronto para Produção
: Implementar tratamento de erros abrangente
: Seguir as melhores práticas de segurança
: Criar arquiteturas mantíveis
Padrões Web Modernos
: Dominar padrões da Fetch API
: Compreender configurações CORS
: Construir UIs responsivas e acessíveis
🎓 Marco de Graduação: Construiu com sucesso uma aplicação web completa orientada a dados utilizando padrões modernos de JavaScript. Estas competências traduzem-se diretamente para trabalho com frameworks como React, Vue ou Angular.
🔄 Capacidades do Próximo Nível:
- Pronto para explorar frameworks frontend que constroem sobre estes conceitos
- Preparado para implementar funcionalidades em tempo real com WebSockets
- Equipado para construir Progressive Web Apps com capacidades offline
- Fundação estabelecida para aprender padrões avançados de gestão de estado
Desafio do Agente GitHub Copilot 🚀
Use o modo Agente para completar o seguinte desafio:
Descrição: Aprimore a aplicação bancária implementando uma funcionalidade de pesquisa e filtro de transações que permita aos utilizadores encontrar transações específicas por intervalo de datas, valor, ou descrição.
Prompt: Crie uma funcionalidade de pesquisa para a aplicação bancária que inclua: 1) Um formulário de pesquisa com campos de entrada para intervalo de datas (de/para), valor mínimo/máximo e palavras-chave na descrição da transação, 2) Uma função filterTransactions() que filtre o array account.transactions com base nos critérios de pesquisa, 3) Atualize a função updateDashboard() para mostrar resultados filtrados, e 4) Adicione um botão "Limpar Filtros" para redefinir a vista. Utilize métodos modernos de arrays JavaScript como filter() e trate casos extremos para critérios de pesquisa vazios.
Saiba mais sobre modo agente aqui.
🚀 Desafio
Pronto para levar a sua aplicação bancária para o próximo nível? Vamos torná-la algo que realmente queira usar. Aqui estão algumas ideias para estimular a sua criatividade:
Deixe-a bonita: Adicione estilos CSS para transformar o seu painel funcional num visual apelativo. Pense em linhas limpas, bom espaçamento e talvez até algumas animações subtis.
Deixe-a responsiva: Tente usar media queries para criar um design responsivo que funcione bem em telemóveis, tablets e computadores. Os seus utilizadores agradecer-lhe-ão!
Adicione um toque especial: Considere codificar as transações por cores (verde para rendimentos, vermelho para despesas), adicionar ícones ou criar efeitos de hover que façam a interface parecer interativa.
Aqui está como um painel polido poderia parecer:
Não sinta que tem de corresponder exatamente a isto – use como inspiração e torne-o seu!
Quiz Pós-Aula
Tarefa
Refatore e comente o seu código
Aviso Legal: Este documento foi traduzido utilizando o serviço de tradução por IA Co-op Translator. Embora nos esforcemos por garantir a precisão, por favor, tenha em conta que traduções automáticas podem conter erros ou imprecisões. O documento original, na sua língua nativa, deve ser considerado a fonte oficial. Para informação crítica, recomenda-se a tradução profissional humana. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações erradas resultantes da utilização desta tradução.



