Прогрессивные веб-приложения: IndexedDB

1. Добро пожаловать

В этой лабораторной работе вы выполните резервное копирование и восстановление клиентских данных в IndexedDB. Это третья из серии сопутствующих практических работ для семинара Progressive Web App . Предыдущая лабораторная работа была посвящена работе с Workbox . В этой серии ещё пять практических работ.

Чему вы научитесь

  • Создайте базу данных IndexedDB и хранилище объектов с помощью idb
  • Добавление и извлечение элементов в хранилище объектов

Что вам следует знать

  • JavaScript и обещания

Что вам понадобится

2. Подготовка

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

Если вы клонируете репозиторий, убедитесь, что вы находитесь на ветке pwa03--indexeddb . ZIP-архив также содержит код для этой ветки.

Для этой кодовой базы требуется Node.js 14 или выше. После того, как код будет готов, выполните команду npm ci из командной строки в папке с кодом, чтобы установить все необходимые зависимости. Затем выполните npm start , чтобы запустить сервер разработки для этой кодовой лаборатории.

Файл README.md исходного кода содержит пояснения ко всем распространяемым файлам. Кроме того, ниже перечислены основные существующие файлы, с которыми вы будете работать в ходе этой лабораторной работы:

Ключевые файлы

  • js/main.js — Основной файл JavaScript приложения

3. Настройте базу данных

Прежде чем использовать базу данных IndexedDB, её необходимо открыть и настроить. Хотя это можно сделать напрямую, поскольку IndexedDB была стандартизирована ещё до того, как Promise стали популярными, её интерфейс, основанный на обратных вызовах, может быть неудобным в использовании. Вместо этого мы будем использовать idb — очень небольшую обёртку Promise для IndexedDB. Для начала импортируем её в js/main.js :

import { openDB } from 'idb';

Затем добавьте следующий код настройки в верхнюю часть прослушивателя событий DOMContentLoaded :

// Set up the database
const db = await openDB('settings-store', 1, {
  upgrade(db) {
    db.createObjectStore('settings');
  },
});

Объяснение

Здесь создаётся база данных IndexedDB с именем settings-store . Её версия инициализируется значением 1 , а сама база данных инициализируется хранилищем объектов с именем settings . Это самый простой тип хранилища объектов, состоящий из простых пар «ключ-значение», но при необходимости можно создавать и более сложные хранилища объектов. Без этой инициализации хранилища объектов данные будет некуда помещать, поэтому оставить это здесь было бы равносильно созданию базы данных без таблиц.

4. Сохранение состояния редактора при обновлении

После инициализации базы данных пришло время сохранить в неё контент! Редактор предоставляет метод onUpdate , который позволяет передать функцию, вызываемую при каждом обновлении контента в редакторе. Это идеальное место для того, чтобы просто нажать на него и внести изменения в базу данных. Для этого добавьте следующий код прямо перед объявлением defaultText в js/main.js :

// Save content to database on edit
editor.onUpdate(async (content) => {
  await db.put('settings', content, 'content');
});

Объяснение

db — это ранее открытая база данных IndexedDB. Метод put позволяет создавать или обновлять записи в хранилище объектов этой базы данных. Первый аргумент — это хранилище объектов в базе данных, которое будет использоваться, второй аргумент — значение для сохранения, а третий аргумент — ключ, по которому будет сохранено значение, если это неясно из значения (в данном случае это не так, поскольку в нашей базе данных нет указанных ключей). Поскольку это асинхронный метод, он заключен в async / await .

5. Получение состояния при загрузке

Наконец, чтобы восстановить текущую работу пользователя, её необходимо загрузить при загрузке редактора. Редактор предоставляет метод setContent , который делает именно это — устанавливает её содержимое. В настоящее время он используется для установки значения defaultText . Чтобы загрузить предыдущую работу пользователя, обновите его следующим кодом:

editor.setContent((await db.get('settings', 'content')) || defaultText);

Объяснение

Вместо того, чтобы просто установить значение defaultText в редакторе, он теперь пытается получить ключ content из хранилища объектов settings в базе данных IndexedDB settings-store . Если это значение существует, оно используется. Если нет, используется текст по умолчанию.

6. Установка и восстановление ночного режима

Теперь, когда вы освоились с IndexedDB, добавьте следующий код в конец js/main.js и обновите его, чтобы сохранять настройки ночного режима пользователя при их изменении и загружать эти настройки при инициализации ночного режима.

// Set up night mode toggle
const { NightMode } = await import('./app/night-mode.js');
new NightMode(
  document.querySelector('#mode'),
  async (mode) => {
    editor.setTheme(mode);
    // Save the night mode setting when changed
  },
  // Retrieve the night mode setting on initialization
);

7. Поздравляем!

Вы узнали, как сохранять и загружать данные из хранилища объектов в IndexedDB.

Следующая лабораторная работа в серии — «От вкладки до панели задач».