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/ru/7-bank-project/3-data
softchris 826e79ce56
🌐 Update translations via Co-op Translator
4 weeks ago
..
README.md 🌐 Update translations via Co-op Translator 4 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 1 month ago

README.md

Создание банковского приложения, часть 3: методы получения и использования данных

Представьте себе компьютер на корабле Enterprise из "Звездного пути" — когда капитан Пикар запрашивает статус корабля, информация появляется мгновенно, без перезагрузки интерфейса. Именно такой плавный поток информации мы создаем здесь с помощью динамического получения данных.

Сейчас ваше банковское приложение похоже на печатную газету — информативно, но статично. Мы превратим его во что-то вроде центра управления полетами NASA, где данные поступают непрерывно и обновляются в реальном времени, не прерывая работу пользователя.

Вы научитесь асинхронно взаимодействовать с серверами, обрабатывать данные, которые поступают в разное время, и преобразовывать сырую информацию в полезную для ваших пользователей. Это разница между демонстрацией и готовым к производству программным обеспечением.

Что можно сделать за следующие 5 минут

Быстрый старт для занятых разработчиков

flowchart LR
    A[⚡ 5 minutes] --> B[Set up API server]
    B --> C[Test fetch with curl]
    C --> D[Create login function]
    D --> E[See data in action]
  • Минута 1-2: Запустите сервер API (cd api && npm start) и протестируйте соединение
  • Минута 3: Создайте базовую функцию getAccount() с использованием fetch
  • Минута 4: Подключите форму входа с action="javascript:login()"
  • Минута 5: Протестируйте вход и посмотрите, как данные аккаунта появляются в консоли

Команды для быстрого тестирования:

# Verify API is running
curl http://localhost:5000/api

# Test account data fetch
curl http://localhost:5000/api/accounts/test

Почему это важно: За 5 минут вы увидите магию асинхронного получения данных, которая лежит в основе каждого современного веб-приложения. Это фундамент, который делает приложения отзывчивыми и живыми.

🗺️ Ваш путь к изучению веб-приложений, управляемых данными

journey
    title From Static Pages to Dynamic Applications
    section Understanding the Evolution
      Traditional page reloads: 3: You
      Discover AJAX/SPA benefits: 5: You
      Master Fetch API patterns: 7: You
    section Building Authentication
      Create login functions: 4: You
      Handle async operations: 6: You
      Manage user sessions: 8: You
    section Dynamic UI Updates
      Learn DOM manipulation: 5: You
      Build transaction displays: 7: You
      Create responsive dashboards: 9: You
    section Professional Patterns
      Template-based rendering: 6: You
      Error handling strategies: 7: You
      Performance optimization: 8: You

Цель вашего пути: К концу этого урока вы поймете, как современные веб-приложения получают, обрабатывают и динамически отображают данные, создавая плавный пользовательский опыт, который мы ожидаем от профессиональных приложений.

Предварительный тест

Предварительный тест

Предварительные требования

Перед тем как углубиться в получение данных, убедитесь, что у вас готовы следующие компоненты:

  • Предыдущий урок: Завершите Форму входа и регистрации — мы будем строить на этой основе
  • Локальный сервер: Установите Node.js и запустите сервер API, чтобы предоставить данные аккаунта
  • Соединение с API: Протестируйте соединение с сервером с помощью этой команды:
curl http://localhost:5000/api
# Expected response: "Bank API v1.0.0"

Этот быстрый тест гарантирует, что все компоненты правильно взаимодействуют:

  • Проверяет, что Node.js работает корректно на вашей системе
  • Подтверждает, что сервер API активен и отвечает
  • Убеждает, что ваше приложение может достичь сервера (как проверка радиосвязи перед миссией)

🧠 Обзор экосистемы управления данными

mindmap
  root((Data Management))
    Authentication Flow
      Login Process
        Form Validation
        Credential Verification
        Session Management
      User State
        Global Account Object
        Navigation Guards
        Error Handling
    API Communication
      Fetch Patterns
        GET Requests
        POST Requests
        Error Responses
      Data Formats
        JSON Processing
        URL Encoding
        Response Parsing
    Dynamic UI Updates
      DOM Manipulation
        Safe Text Updates
        Element Creation
        Template Cloning
      User Experience
        Real-time Updates
        Error Messages
        Loading States
    Security Considerations
      XSS Prevention
        textContent Usage
        Input Sanitization
        Safe HTML Creation
      CORS Handling
        Cross-Origin Requests
        Header Configuration
        Development Setup

Основной принцип: Современные веб-приложения — это системы оркестрации данных, которые координируют взаимодействие между пользовательскими интерфейсами, серверными API и моделями безопасности браузера для создания плавного и отзывчивого опыта.


Понимание получения данных в современных веб-приложениях

То, как веб-приложения обрабатывают данные, значительно изменилось за последние два десятилетия. Понимание этой эволюции поможет вам оценить, почему современные методы, такие как AJAX и Fetch API, настолько мощны и почему они стали необходимыми инструментами для веб-разработчиков.

Давайте рассмотрим, как работали традиционные веб-сайты по сравнению с динамическими, отзывчивыми приложениями, которые мы создаем сегодня.

Традиционные многостраничные приложения (MPA)

В ранние дни веба каждый клик был похож на переключение каналов на старом телевизоре — экран становился пустым, а затем медленно загружал новый контент. Это была реальность ранних веб-приложений, где каждое взаимодействие означало полную перезагрузку всей страницы.

sequenceDiagram
    participant User
    participant Browser
    participant Server
    
    User->>Browser: Clicks link or submits form
    Browser->>Server: Requests new HTML page
    Note over Browser: Page goes blank
    Server->>Browser: Returns complete HTML page
    Browser->>User: Displays new page (flash/reload)

Рабочий процесс обновления в многостраничном приложении

Почему этот подход казался неудобным:

  • Каждый клик означал полную перезагрузку страницы
  • Пользователи прерывались на середине мысли из-за раздражающих миганий страницы
  • Ваше интернет-соединение работало на пределе, загружая один и тот же заголовок и подвал снова и снова
  • Приложения больше походили на просмотр картотеки, чем на использование программного обеспечения

Современные одностраничные приложения (SPA)

AJAX (асинхронный JavaScript и XML) полностью изменил эту парадигму. Как модульная конструкция Международной космической станции, где астронавты могут заменять отдельные компоненты без перестройки всей структуры, AJAX позволяет нам обновлять конкретные части веб-страницы без перезагрузки всего. Несмотря на то, что в названии упоминается XML, сегодня мы в основном используем JSON, но основной принцип остается: обновлять только то, что нужно.

sequenceDiagram
    participant User
    participant Browser
    participant JavaScript
    participant Server
    
    User->>Browser: Interacts with page
    Browser->>JavaScript: Triggers event handler
    JavaScript->>Server: Fetches only needed data
    Server->>JavaScript: Returns JSON data
    JavaScript->>Browser: Updates specific page elements
    Browser->>User: Shows updated content (no reload)

Рабочий процесс обновления в одностраничном приложении

Почему SPA намного удобнее:

  • Обновляются только те части, которые действительно изменились (умно, правда?)
  • Больше никаких резких прерываний — пользователи остаются в своем потоке
  • Меньше данных передается по сети, что означает более быструю загрузку
  • Все кажется быстрым и отзывчивым, как приложения на вашем телефоне

Эволюция к современному Fetch API

Современные браузеры предоставляют Fetch API, который заменяет устаревший XMLHttpRequest. Как разница между использованием телеграфа и электронной почты, Fetch API использует промисы для более чистого асинхронного кода и естественно обрабатывает JSON.

Функция XMLHttpRequest Fetch API
Синтаксис Сложный, основанный на обратных вызовах Чистый, основанный на промисах
Обработка JSON Требуется ручной парсинг Встроенный метод .json()
Обработка ошибок Ограниченная информация об ошибках Полная информация об ошибках
Современная поддержка Совместимость с устаревшими системами Поддержка промисов ES6+ и async/await

💡 Совместимость с браузерами: Хорошие новости — Fetch API работает во всех современных браузерах! Если вам интересно узнать о конкретных версиях, caniuse.com предоставит полную информацию о совместимости.

Итог:

  • Отлично работает в Chrome, Firefox, Safari и Edge (везде, где находятся ваши пользователи)
  • Только Internet Explorer требует дополнительной поддержки (и честно говоря, пора отпустить IE)
  • Идеально подходит для элегантных паттернов async/await, которые мы будем использовать позже

Реализация входа пользователя и получения данных

Теперь давайте реализуем систему входа, которая преобразует ваше банковское приложение из статического отображения в функциональное приложение. Как протоколы аутентификации, используемые в защищенных военных объектах, мы проверим учетные данные пользователя, а затем предоставим доступ к его конкретным данным.

Мы будем строить это постепенно, начиная с базовой аутентификации и затем добавляя возможности получения данных.

Шаг 1: Создание основы функции входа

Откройте ваш файл app.js и добавьте новую функцию login. Она будет обрабатывать процесс аутентификации пользователя:

async function login() {
  const loginForm = document.getElementById('loginForm');
  const user = loginForm.user.value;
}

Разберем это:

  • Ключевое слово async говорит JavaScript: "Эй, эта функция может потребовать ожидания"
  • Мы находим нашу форму на странице (ничего сложного, просто ищем ее по ID)
  • Затем извлекаем то, что пользователь ввел в качестве имени пользователя
  • Вот хитрость: вы можете получить доступ к любому элементу формы через его атрибут name — не нужно дополнительных вызовов getElementById!

💡 Шаблон доступа к форме: Каждый элемент формы можно получить через его имя (установленное в HTML с помощью атрибута name) как свойство элемента формы. Это обеспечивает чистый и удобочитаемый способ получения данных формы.

Шаг 2: Создание функции получения данных аккаунта

Далее мы создадим отдельную функцию для получения данных аккаунта с сервера. Это следует той же схеме, что и ваша функция регистрации, но сосредоточено на извлечении данных:

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' };
  }
}

Что делает этот код:

  • Использует современный fetch API для асинхронного запроса данных
  • Формирует URL-адрес GET-запроса с параметром имени пользователя
  • Применяет encodeURIComponent() для безопасной обработки специальных символов в URL
  • Преобразует ответ в формат JSON для удобной обработки данных
  • Обрабатывает ошибки, возвращая объект ошибки вместо сбоя

⚠️ Примечание по безопасности: Функция encodeURIComponent() обрабатывает специальные символы в URL. Как системы кодирования в военных коммуникациях, она гарантирует, что ваше сообщение будет доставлено точно так, как задумано, предотвращая неправильную интерпретацию символов, таких как "#" или "&".

Почему это важно:

  • Предотвращает сбои URL из-за специальных символов
  • Защищает от атак с манипуляцией URL
  • Гарантирует, что сервер получает запрошенные данные
  • Следует безопасным практикам кодирования

Понимание HTTP GET-запросов

Вот что может вас удивить: когда вы используете fetch без дополнительных опций, он автоматически создает GET запрос. Это идеально подходит для того, что мы делаем — спрашиваем сервер: "Эй, могу ли я увидеть данные аккаунта этого пользователя?"

Думайте о GET-запросах как о вежливой просьбе взять книгу в библиотеке — вы запрашиваете что-то, что уже существует. POST-запросы (которые мы использовали для регистрации) больше похожи на отправку новой книги для добавления в коллекцию.

GET-запрос POST-запрос
Цель Получение существующих данных
Параметры В пути URL/строке запроса
Кэширование Может быть кэшировано браузерами
Безопасность Видно в URL/логах
sequenceDiagram
    participant B as Browser
    participant S as Server
    
    Note over B,S: GET Request (Data Retrieval)
    B->>S: GET /api/accounts/test
    S-->>B: 200 OK + Account Data
    
    Note over B,S: POST Request (Data Submission)
    B->>S: POST /api/accounts + New Account Data
    S-->>B: 201 Created + Confirmation
    
    Note over B,S: Error Handling
    B->>S: GET /api/accounts/nonexistent
    S-->>B: 404 Not Found + Error Message

Шаг 3: Объединение всех частей

Теперь самая приятная часть — давайте подключим вашу функцию получения данных аккаунта к процессу входа. Здесь все становится на свои места:

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');
}

Эта функция следует четкой последовательности:

  • Извлекает имя пользователя из ввода формы
  • Запрашивает данные аккаунта пользователя с сервера
  • Обрабатывает любые ошибки, возникающие в процессе
  • Сохраняет данные аккаунта и переходит на панель управления при успешном выполнении

🎯 Паттерн Async/Await: Поскольку getAccount — асинхронная функция, мы используем ключевое слово await, чтобы приостановить выполнение до получения ответа от сервера. Это предотвращает продолжение выполнения кода с неопределенными данными.

Шаг 4: Создание хранилища для данных

Вашему приложению нужно место, где оно будет хранить информацию об аккаунте после загрузки. Думайте об этом как о краткосрочной памяти вашего приложения — месте, где хранятся данные текущего пользователя. Добавьте эту строку в начало вашего файла app.js:

// This holds the current user's account data
let account = null;

Почему это необходимо:

  • Держит данные аккаунта доступными из любой части вашего приложения
  • Начало с null означает, что пока никто не вошел в систему
  • Обновляется, когда кто-то успешно входит или регистрируется
  • Действует как единый источник правды — никакой путаницы о том, кто вошел

Шаг 5: Подключение вашей формы

Теперь давайте подключим вашу новую функцию входа к HTML-форме. Обновите тег формы следующим образом:

<form id="loginForm" action="javascript:login()">
  <!-- Your existing form inputs -->
</form>

Что делает это небольшое изменение:

  • Останавливает стандартное поведение формы "перезагрузить всю страницу"
  • Вызывает вашу пользовательскую функцию JavaScript вместо этого
  • Сохраняет все плавным и в стиле одностраничного приложения
  • Дает вам полный контроль над тем, что происходит, когда пользователи нажимают "Войти"

Шаг 6: Улучшение функции регистрации

Для согласованности обновите вашу функцию register, чтобы она также сохраняла данные аккаунта и переходила на панель управления:

// Add these lines at the end of your register function
account = result;
navigate('/dashboard');

Это улучшение обеспечивает:

  • Плавный переход от регистрации к панели управления
  • Согласованный пользовательский опыт между процессами входа и регистрации
  • Мгновенный доступ к данным аккаунта после успешной регистрации

Тестирование вашей реализации

flowchart TD
    A[User enters credentials] --> B[Login function called]
    B --> C[Fetch account data from server]
    C --> D{Data received successfully?}
    D -->|Yes| E[Store account data globally]
    D -->|No| F[Display error message]
    E --> G[Navigate to dashboard]
    F --> H[User stays on login page]

Пора протестировать:

  1. Создайте новый аккаунт, чтобы убедиться, что все работает
  2. Попробуйте войти с этими же учетными данными
  3. Загляните в консоль браузера (F12), если что-то кажется неправильным
  4. Убедитесь, что вы попадаете на панель управления после успешного входа

Если что-то не работает, не паникуйте! Большинство проблем легко исправить, например, опечатки или забытый запуск сервера API.

Несколько слов о магии кросс-доменного взаимодействия

Вы можете задаться вопросом: "Как мое веб-приложение общается с этим сервером API, если они работают на разных портах?" Отличный вопрос! Это касается того, с чем сталкивается каждый веб-разработчик.

🔒 Кросс-доменная безопасность: Браузеры применяют "политику одного источника", чтобы предотвратить несанкционированное взаимодействие между различными доменами. Как система пропусков в Пентагоне, они проверяют, что взаимодействие разрешено, прежде чем разрешить передачу данных.

В нашей настройке:

  • Ваше веб-приложение работает на localhost:3000 (сервер разработки)
  • Ваш сервер API работает на localhost:5000 (сервер бэкэнда)
  • Сервер API включает заголовки CORS, которые явно разрешают взаимодействие с вашим веб-приложением

Эта конфигурация отражает реальную разработку, где фронтенд и бэкэнд приложения обычно работают на отдельных серверах.

📚 Узнать больше: Узнайте больше о API и получении данных с этим подробным модулем Microsoft Learn об API.

Превращение данных в HTML

Теперь мы сделаем полученные данные видимыми для пользователей через манипуляцию DOM. Как процесс проявления фотографий в темной комнате, мы превращаем невидимые данные в то, что пользователи могут видеть и с чем взаимодействовать. Манипуляция DOM — это техника, которая превращает статичные веб-страницы в динамические приложения, обновляющие свой контент на основе взаимодействий пользователя и ответов сервера.

Выбор подходящего инструмента для задачи

Когда дело доходит до обновления HTML с помощью JavaScript, у вас есть несколько вариантов. Представьте их как разные инструменты в ящике — каждый идеально подходит для определенных задач:

Метод Для чего подходит Когда использовать Уровень безопасности
textContent Безопасное отображение данных пользователя Всегда, когда нужно показать текст Надежно
createElement() + append() Создание сложных макетов Создание новых секций/списков Безопасно
innerHTML Установка HTML-контента ⚠️ Лучше избегать Рискованно

Безопасный способ отображения текста: textContent

Свойство textContent — ваш лучший друг для отображения данных пользователя. Это как охранник для вашей веб-страницы — ничего вредоносного не пройдет:

// The safe, reliable way to update text
const balanceElement = document.getElementById('balance');
balanceElement.textContent = account.balance;

Преимущества textContent:

  • Обрабатывает все как простой текст (предотвращает выполнение скриптов)
  • Автоматически очищает существующий контент
  • Эффективен для простых обновлений текста
  • Обеспечивает встроенную защиту от вредоносного контента

Создание динамических HTML-элементов

Для более сложного контента комбинируйте document.createElement() с методом append():

// Safe way to create new elements
const transactionItem = document.createElement('div');
transactionItem.className = 'transaction-item';
transactionItem.textContent = `${transaction.date}: ${transaction.description}`;
container.append(transactionItem);

Понимание подхода:

  • Создает новые элементы DOM программно
  • Обеспечивает полный контроль над атрибутами и содержимым элементов
  • Позволяет создавать сложные, вложенные структуры элементов
  • Сохраняет безопасность, разделяя структуру и контент

⚠️ Соображения безопасности: Хотя innerHTML часто встречается в учебных материалах, он может выполнять встроенные скрипты. Как протоколы безопасности в CERN, предотвращающие выполнение несанкционированного кода, использование textContent и createElement обеспечивает более безопасные альтернативы.

Риски innerHTML:

  • Выполняет любые теги <script> в данных пользователя
  • Уязвим для атак с внедрением кода
  • Создает потенциальные уязвимости безопасности
  • Более безопасные альтернативы, которые мы используем, предоставляют аналогичный функционал

Создание удобных для пользователя сообщений об ошибках

В настоящее время ошибки входа отображаются только в консоли браузера, что невидимо для пользователей. Как разница между внутренней диагностикой пилота и системой информации для пассажиров, нам нужно передавать важную информацию через подходящий канал.

Реализация видимых сообщений об ошибках дает пользователям немедленную обратную связь о том, что пошло не так и как действовать дальше.

Шаг 1: Добавьте место для сообщений об ошибках

Сначала создайте место для сообщений об ошибках в вашем HTML. Добавьте это прямо перед кнопкой входа, чтобы пользователи видели его естественным образом:

<!-- This is where error messages will appear -->
<div id="loginError" role="alert"></div>
<button>Login</button>

Что здесь происходит:

  • Мы создаем пустой контейнер, который остается невидимым до тех пор, пока он не понадобится
  • Он расположен там, где пользователи естественным образом смотрят после нажатия на "Войти"
  • Атрибут role="alert" — это приятное дополнение для экранных читалок — он сообщает вспомогательным технологиям: "Эй, это важно!"
  • Уникальный id дает нашему JavaScript легкую цель

Шаг 2: Создайте удобную вспомогательную функцию

Давайте создадим небольшую утилиту, которая может обновлять текст любого элемента. Это одна из тех функций "напиши один раз, используй везде", которая сэкономит вам время:

function updateElement(id, text) {
  const element = document.getElementById(id);
  element.textContent = text;
}

Преимущества функции:

  • Простой интерфейс, требующий только ID элемента и текстового содержимого
  • Безопасно находит и обновляет элементы DOM
  • Повторяемый шаблон, который уменьшает дублирование кода
  • Обеспечивает согласованное поведение обновления по всему приложению

Шаг 3: Показывайте ошибки там, где их видят пользователи

Теперь заменим скрытое сообщение в консоли на то, что пользователи действительно смогут увидеть. Обновите вашу функцию входа:

// Instead of just logging to console, show the user what's wrong
if (data.error) {
  return updateElement('loginError', data.error);
}

Это небольшое изменение имеет большое значение:

  • Сообщения об ошибках появляются прямо там, где смотрят пользователи
  • Больше никаких загадочных тихих сбоев
  • Пользователи получают немедленную, полезную обратную связь
  • Ваше приложение начинает выглядеть профессионально и заботливо

Теперь, когда вы протестируете с недействительным аккаунтом, вы увидите полезное сообщение об ошибке прямо на странице!

Скриншот, показывающий сообщение об ошибке при входе

Шаг 4: Забота об инклюзивности и доступности

Вот что круто в том role="alert", который мы добавили ранее — это не просто украшение! Этот небольшой атрибут создает так называемую живую область, которая немедленно объявляет изменения экранным читалкам:

<div id="loginError" role="alert"></div>

Почему это важно:

  • Пользователи экранных читалок слышат сообщение об ошибке, как только оно появляется
  • Все получают одинаковую важную информацию, независимо от того, как они взаимодействуют с приложением
  • Это простой способ сделать ваше приложение доступным для большего числа людей
  • Показывает, что вы заботитесь о создании инклюзивного опыта

Такие мелочи отличают хороших разработчиков от отличных!

🎯 Педагогическая проверка: шаблоны аутентификации

Пауза и размышление: Вы только что реализовали полный поток аутентификации. Это базовый шаблон в веб-разработке.

Быстрая самооценка:

  • Можете ли вы объяснить, почему мы используем async/await для вызовов API?
  • Что произойдет, если мы забудем функцию encodeURIComponent()?
  • Как наше обработка ошибок улучшает пользовательский опыт?

Связь с реальным миром: Шаблоны, которые вы изучили здесь (асинхронное получение данных, обработка ошибок, обратная связь с пользователем), используются в каждом крупном веб-приложении — от социальных сетей до сайтов электронной коммерции. Вы развиваете навыки уровня производства!

Вопрос для размышления: Как вы могли бы модифицировать эту систему аутентификации для работы с несколькими ролями пользователей (клиент, администратор, кассир)? Подумайте о структуре данных и изменениях в интерфейсе.

Шаг 5: Примените тот же шаблон к регистрации

Для согласованности реализуйте идентичную обработку ошибок в вашей форме регистрации:

  1. Добавьте элемент отображения ошибок в ваш HTML регистрации:
<div id="registerError" role="alert"></div>
  1. Обновите вашу функцию регистрации, чтобы использовать тот же шаблон отображения ошибок:
if (data.error) {
  return updateElement('registerError', data.error);
}

Преимущества согласованной обработки ошибок:

  • Обеспечивает единообразный пользовательский опыт во всех формах
  • Уменьшает когнитивную нагрузку, используя знакомые шаблоны
  • Упрощает обслуживание с помощью повторяемого кода
  • Гарантирует соблюдение стандартов доступности по всему приложению

Создание вашего динамического дашборда

Теперь мы преобразуем ваш статичный дашборд в динамический интерфейс, который отображает реальные данные аккаунта. Как разница между напечатанным расписанием рейсов и живыми табло вылетов в аэропортах, мы переходим от статичной информации к актуальным, отзывчивым отображениям.

Используя техники манипуляции DOM, которые вы изучили, мы создадим дашборд, который автоматически обновляется с текущей информацией аккаунта.

Знакомство с вашими данными

Прежде чем начать разработку, давайте взглянем на данные, которые ваш сервер отправляет обратно. Когда кто-то успешно входит в систему, вот кладезь информации, с которой вы можете работать:

{
  "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 }
  ]
}

Эта структура данных предоставляет:

  • user: Идеально для персонализации опыта ("Добро пожаловать обратно, Сара!")
  • currency: Убедитесь, что мы правильно отображаем денежные суммы
  • description: Дружественное название аккаунта
  • balance: Важнейший текущий баланс
  • transactions: Полная история транзакций со всеми деталями

Все, что нужно для создания профессионального банковского дашборда!

flowchart TD
    A[User Login] --> B[Fetch Account Data]
    B --> C{Data Valid?}
    C -->|Yes| D[Store in Global Variable]
    C -->|No| E[Show Error Message]
    D --> F[Navigate to Dashboard]
    F --> G[Update UI Elements]
    G --> H[Display Balance]
    G --> I[Show Description]
    G --> J[Render Transactions]
    J --> K[Create Table Rows]
    K --> L[Format Currency]
    L --> M[User Sees Live Data]

💡 Полезный совет: Хотите сразу увидеть ваш дашборд в действии? Используйте имя пользователя test при входе — оно уже загружено с примерными данными, чтобы вы могли увидеть, как все работает, не создавая сначала транзакции.

Почему тестовый аккаунт удобен:

  • Уже содержит реалистичные примерные данные
  • Идеально для просмотра отображения транзакций
  • Отлично подходит для тестирования функций дашборда
  • Экономит время на создание фиктивных данных вручную

Создание элементов отображения дашборда

Давайте шаг за шагом создадим интерфейс вашего дашборда, начиная с информации о счете и переходя к более сложным функциям, таким как списки транзакций.

Шаг 1: Обновите структуру HTML

Сначала замените статичный раздел "Баланс" на динамические элементы-заполнители, которые ваш JavaScript сможет заполнить:

<section>
  Balance: <span id="balance"></span><span id="currency"></span>
</section>

Затем добавьте раздел для описания аккаунта. Поскольку это действует как заголовок для контента дашборда, используйте семантический HTML:

<h2 id="description"></h2>

Понимание структуры HTML:

  • Использует отдельные элементы <span> для баланса и валюты для индивидуального контроля
  • Применяет уникальные ID к каждому элементу для целевой работы JavaScript
  • Следует семантическому HTML, используя <h2> для описания аккаунта
  • Создает логическую иерархию для экранных читалок и SEO

Инсайт доступности: Описание аккаунта функционирует как заголовок для контента дашборда, поэтому оно размечено семантически как заголовок. Узнайте больше о том, как структура заголовков влияет на доступность. Можете ли вы определить другие элементы на вашей странице, которые могли бы выиграть от использования тегов заголовков?

Шаг 2: Создайте функцию обновления дашборда

Теперь создайте функцию, которая заполняет ваш дашборд реальными данными аккаунта:

function updateDashboard() {
  if (!account) {
    return navigate('/login');
  }

  updateElement('description', account.description);
  updateElement('balance', account.balance.toFixed(2));
  updateElement('currency', account.currency);
}

Шаг за шагом, что делает эта функция:

  • Проверяет, что данные аккаунта существуют перед продолжением
  • Перенаправляет неавторизованных пользователей обратно на страницу входа
  • Обновляет описание аккаунта, используя повторяемую функцию updateElement
  • Форматирует баланс, чтобы всегда показывать два знака после запятой
  • Отображает соответствующий символ валюты

💰 Форматирование денег: Метод toFixed(2) — это спасение! Он гарантирует, что ваш баланс всегда выглядит как настоящие деньги — "75.00" вместо просто "75". Ваши пользователи оценят знакомое форматирование валюты.

Шаг 3: Убедитесь, что ваш дашборд обновляется

Чтобы гарантировать, что ваш дашборд обновляется с текущими данными каждый раз, когда кто-то посещает его, нам нужно подключиться к вашей системе навигации. Если вы завершили задание из урока 1, это должно быть вам знакомо. Если нет, не переживайте — вот что нужно:

Добавьте это в конец вашей функции updateRoute():

if (typeof route.init === 'function') {
  route.init();
}

Затем обновите ваши маршруты, чтобы включить инициализацию дашборда:

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard', init: updateDashboard }
};

Что делает эта умная настройка:

  • Проверяет, есть ли у маршрута специальный код инициализации
  • Автоматически запускает этот код при загрузке маршрута
  • Гарантирует, что ваш дашборд всегда показывает свежие, актуальные данные
  • Сохраняет логику маршрутизации чистой и организованной

Тестирование вашего дашборда

После реализации этих изменений протестируйте ваш дашборд:

  1. Войдите с тестовым аккаунтом
  2. Убедитесь, что вас перенаправляют на дашборд
  3. Проверьте, что описание аккаунта, баланс и валюта отображаются правильно
  4. Попробуйте выйти и снова войти, чтобы убедиться, что данные обновляются правильно

Ваш дашборд теперь должен отображать динамическую информацию аккаунта, которая обновляется на основе данных вошедшего пользователя!

Создание умных списков транзакций с помощью шаблонов

Вместо ручного создания HTML для каждой транзакции мы будем использовать шаблоны для автоматического создания согласованного форматирования. Как стандартизированные компоненты, используемые в производстве космических аппаратов, шаблоны обеспечивают, что каждая строка транзакции следует одной и той же структуре и внешнему виду.

Этот метод эффективно масштабируется от нескольких транзакций до тысяч, поддерживая согласованность производительности и представления.

graph LR
    A[HTML Template] --> B[JavaScript Clone]
    B --> C[Populate with Data]
    C --> D[Add to Fragment]
    D --> E[Batch Insert to DOM]
    
    subgraph "Performance Benefits"
        F[Single DOM Update]
        G[Consistent Formatting]
        H[Reusable Pattern]
    end
    
    E --> F
    E --> G
    E --> H
flowchart LR
    A[Transaction Data] --> B[HTML Template]
    B --> C[Clone Template]
    C --> D[Populate with Data]
    D --> E[Add to DOM]
    E --> F[Repeat for Each Transaction]

Шаг 1: Создайте шаблон транзакции

Сначала добавьте повторяемый шаблон для строк транзакций в ваш HTML <body>:

<template id="transaction">
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</template>

Понимание HTML-шаблонов:

  • Определяет структуру для одной строки таблицы
  • Остается невидимым до клонирования и заполнения с помощью JavaScript
  • Включает три ячейки для даты, описания и суммы
  • Обеспечивает повторяемый шаблон для согласованного форматирования

Шаг 2: Подготовьте вашу таблицу для динамического контента

Затем добавьте id к телу таблицы, чтобы JavaScript мог легко его найти:

<tbody id="transactions"></tbody>

Что это дает:

  • Создает четкую цель для вставки строк транзакций
  • Разделяет структуру таблицы от динамического контента
  • Позволяет легко очищать и заполнять данные транзакций

Шаг 3: Создайте фабричную функцию для строк транзакций

Теперь создайте функцию, которая преобразует данные транзакций в 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;
}

Разбор фабричной функции:

  • Находит элемент шаблона по его ID
  • Клонирует содержимое шаблона для безопасной манипуляции
  • Выбирает строку таблицы в клонированном содержимом
  • Заполняет каждую ячейку данными транзакции
  • Форматирует сумму, чтобы показать правильное количество знаков после запятой
  • Возвращает завершенную строку, готовую к вставке

Шаг 4: Эффективное создание нескольких строк транзакций

Добавьте этот код в вашу функцию updateDashboard(), чтобы отображать все транзакции:

const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
  const transactionRow = createTransactionRow(transaction);
  transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);

Понимание этого эффективного подхода:

  • Создает фрагмент документа для пакетных операций с DOM
  • Итерирует все транзакции в данных аккаунта
  • Генерирует строку для каждой транзакции с помощью фабричной функции
  • Собирает все строки во фрагмент перед добавлением в DOM
  • Выполняет одно обновление DOM вместо множества отдельных вставок

Оптимизация производительности: document.createDocumentFragment() работает как сборочный процесс на заводе Boeing - компоненты готовятся отдельно от основной линии, а затем устанавливаются как единое целое. Такой подход к пакетной обработке минимизирует перерисовку DOM, выполняя одну вставку вместо множества отдельных операций.

Шаг 5: Улучшение функции обновления для смешанного контента

Ваша функция updateElement() в настоящее время обрабатывает только текстовый контент. Обновите её, чтобы она могла работать как с текстом, так и с DOM-узлами:

function updateElement(id, textOrNode) {
  const element = document.getElementById(id);
  element.textContent = ''; // Removes all children
  element.append(textOrNode);
}

Основные улучшения в этом обновлении:

  • Очищает существующий контент перед добавлением нового
  • Принимает как текстовые строки, так и DOM-узлы в качестве параметров
  • Использует метод append() для гибкости
  • Сохраняет обратную совместимость с существующим текстовым использованием

Тестирование вашей панели управления

Настал момент истины! Давайте посмотрим, как работает ваша динамическая панель управления:

  1. Войдите в систему, используя учетную запись test (в ней уже есть готовые данные)
  2. Перейдите на вашу панель управления
  3. Убедитесь, что строки транзакций отображаются с правильным форматированием
  4. Проверьте, что даты, описания и суммы выглядят корректно

Если всё работает, вы должны увидеть полностью функциональный список транзакций на вашей панели управления! 🎉

Чего вы достигли:

  • Создали панель управления, которая масштабируется под любой объем данных
  • Разработали шаблоны для единообразного форматирования
  • Реализовали эффективные методы манипуляции DOM
  • Создали функциональность, сопоставимую с банковскими приложениями уровня производства

Вы успешно преобразовали статичную веб-страницу в динамическое веб-приложение.

🎯 Педагогическая проверка: Генерация динамического контента

Понимание архитектуры: Вы реализовали сложный процесс преобразования данных в пользовательский интерфейс, который отражает шаблоны, используемые в таких фреймворках, как React, Vue и Angular.

Ключевые освоенные концепции:

  • Рендеринг на основе шаблонов: Создание повторно используемых компонентов интерфейса
  • Фрагменты документа: Оптимизация производительности DOM
  • Безопасная манипуляция DOM: Предотвращение уязвимостей безопасности
  • Преобразование данных: Конвертация данных сервера в пользовательские интерфейсы

Связь с индустрией: Эти техники составляют основу современных фронтенд-фреймворков. Виртуальный DOM в React, система шаблонов в Vue и архитектура компонентов в Angular строятся на этих базовых концепциях.

Вопрос для размышления: Как бы вы расширили эту систему для обработки обновлений в реальном времени (например, автоматическое появление новых транзакций)? Рассмотрите использование WebSockets или Server-Sent Events.


📈 Ваш таймлайн освоения управления данными

timeline
    title Data-Driven Development Journey
    
    section Foundation Building
        API Setup & Testing
            : Understand client-server communication
            : Master HTTP request/response cycle
            : Learn debugging techniques
    
    section Authentication Mastery
        Async Function Patterns
            : Write clean async/await code
            : Handle promises effectively
            : Implement error boundaries
        User Session Management
            : Create global state patterns
            : Build navigation guards
            : Design user feedback systems
    
    section Dynamic UI Development
        Safe DOM Manipulation
            : Prevent XSS vulnerabilities
            : Use textContent over innerHTML
            : Create accessibility-friendly interfaces
        Template Systems
            : Build reusable UI components
            : Optimize performance with fragments
            : Scale to handle large datasets
    
    section Professional Patterns
        Production-Ready Code
            : Implement comprehensive error handling
            : Follow security best practices
            : Create maintainable architectures
        Modern Web Standards
            : Master Fetch API patterns
            : Understand CORS configurations
            : Build responsive, accessible UIs

🎓 Этап завершения обучения: Вы успешно создали полноценное веб-приложение, управляемое данными, используя современные шаблоны JavaScript. Эти навыки напрямую применимы к работе с фреймворками, такими как React, Vue или Angular.

🔄 Возможности следующего уровня:

  • Готовы изучать фронтенд-фреймворки, которые строятся на этих концепциях
  • Подготовлены к реализации функций в реальном времени с использованием WebSockets
  • Оснащены для создания прогрессивных веб-приложений с возможностями оффлайн-режима
  • Заложена основа для изучения сложных паттернов управления состоянием

Вызов GitHub Copilot Agent 🚀

Используйте режим Agent, чтобы выполнить следующий вызов:

Описание: Улучшите банковское приложение, добавив функцию поиска и фильтрации транзакций, которая позволяет пользователям находить конкретные транзакции по диапазону дат, сумме или ключевым словам в описании.

Задание: Создайте функцию поиска для банковского приложения, которая включает: 1) Форма поиска с полями ввода для диапазона дат (от/до), минимальной/максимальной суммы и ключевых слов описания транзакции, 2) Функцию filterTransactions(), которая фильтрует массив account.transactions на основе критериев поиска, 3) Обновите функцию updateDashboard(), чтобы отображать отфильтрованные результаты, и 4) Добавьте кнопку "Очистить фильтры" для сброса представления. Используйте современные методы массива JavaScript, такие как filter(), и обработайте крайние случаи для пустых критериев поиска.

Узнайте больше о режиме Agent здесь.

🚀 Вызов

Готовы вывести ваше банковское приложение на новый уровень? Давайте сделаем его таким, чтобы им действительно хотелось пользоваться. Вот несколько идей для вдохновения:

Сделайте его красивым: Добавьте CSS-стили, чтобы преобразовать вашу функциональную панель управления в нечто визуально привлекательное. Подумайте о чистых линиях, хорошем расстоянии и, возможно, даже о легких анимациях.

Сделайте его адаптивным: Попробуйте использовать медиа-запросы, чтобы создать адаптивный дизайн, который отлично работает на телефонах, планшетах и настольных компьютерах. Ваши пользователи будут благодарны!

Добавьте немного изюминки: Рассмотрите возможность цветового кодирования транзакций (зеленый для доходов, красный для расходов), добавления иконок или создания эффектов наведения, которые сделают интерфейс более интерактивным.

Вот как может выглядеть стильная панель управления:

Скриншот примера результата панели управления после стилизации

Не обязательно точно копировать этот пример - используйте его как вдохновение и создайте что-то свое!

Викторина после лекции

Викторина после лекции

Задание

Рефакторизуйте и прокомментируйте ваш код


Отказ от ответственности:
Этот документ был переведен с использованием сервиса автоматического перевода Co-op Translator. Хотя мы стремимся к точности, пожалуйста, учитывайте, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на его родном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется профессиональный перевод человеком. Мы не несем ответственности за любые недоразумения или неправильные интерпретации, возникающие в результате использования данного перевода.