You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/pt/7-bank-project/3-data
localizeflow[bot] 72504672c7
chore(i18n): sync translations with latest source changes (chunk 11/20, 100 files)
4 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 11/20, 100 files) 4 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 11/20, 100 files) 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

Questionário pré-aula

Pré-requisitos

Antes de mergulhar na obtenção de dados, tenha estes componentes prontos:

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)

Fluxo de atualização numa aplicação de múltiplas páginas

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)

Fluxo de atualização numa aplicação de página única

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 fetch para 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-chave await para 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 null significa "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:

  1. Crie uma nova conta para garantir que tudo funciona
  2. Tente fazer login com essas mesmas credenciais
  3. Espie a consola do seu navegador (F12) se algo parecer estranho
  4. 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 innerHTML apareç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, usar textContent e createElement oferece 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!

Screenshot mostrando a mensagem de erro exibida durante o login

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:

  1. Adicione um elemento de exibição de erros ao seu HTML do registo:
<div id="registerError" role="alert"></div>
  1. 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 corretamente
  • description: Um nome amigável para a conta
  • balance: O saldo atual, muito importante
  • transactions: 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 test quando 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:

  1. Faça login com uma conta de teste
  2. Verifique se é redirecionado para o painel
  3. Confirme que a descrição da conta, o saldo e a moeda aparecem corretamente
  4. 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:

  1. Inicie sessão com a conta test (tem dados de exemplo prontos para usar)
  2. Navegue até ao seu painel
  3. Verifique se as linhas das transações aparecem com formatação correta
  4. 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:

Screenshot of an example result of the dashboard after styling

Não sinta que tem de corresponder exatamente a isto use como inspiração e torne-o seu!

Quiz Pós-Aula

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.