Progresywne aplikacje internetowe: IndexedDB

1. Witamy

W tym module utworzysz kopię zapasową danych klienta i przywrócisz je do IndexedDB. To trzecie z serii powiązanych ćwiczeń z kodem do warsztatów dotyczących progresywnych aplikacji internetowych. Poprzednie laboratorium kodowania to Praca z Workbox. Ta seria zawiera jeszcze 5 samouczków.

Czego się nauczysz

  • Tworzenie bazy danych IndexedDB i magazynu obiektów za pomocą idb
  • Dodawanie i pobieranie elementów z usługi przechowywania obiektów

Co warto wiedzieć

  • JavaScript i obietnice

Wymagania

2. Pierwsze kroki

Zacznij od sklonowania lub pobrania kodu startowego potrzebnego do ukończenia tego ćwiczenia:

Jeśli klonujesz repozytorium, upewnij się, że jesteś w gałęzi pwa03--indexeddb. Plik ZIP zawiera też kod tej gałęzi.

Ten kod wymaga Node.js w wersji 14 lub nowszej. Gdy kod będzie dostępny, uruchom npm ci z wiersza poleceń w folderze kodu, aby zainstalować wszystkie potrzebne zależności. Następnie uruchom npm start, aby uruchomić serwer programistyczny dla tego laboratorium.

Plik README.md kodu źródłowego zawiera wyjaśnienie wszystkich rozpowszechnianych plików. Oto najważniejsze pliki, z którymi będziesz pracować w trakcie tego ćwiczenia:

Kluczowe pliki

  • js/main.js – główny plik JavaScript aplikacji

3. Konfigurowanie bazy danych

Zanim będzie można używać bazy danych IndexedDB, należy ją otworzyć i skonfigurować. Możesz to zrobić bezpośrednio, ale ponieważ IndexedDB została ustandaryzowana, zanim obietnice stały się popularne, jej interfejs oparty na wywołaniach zwrotnych może być niewygodny w użyciu. Zamiast tego będziemy używać idb, czyli bardzo małej otoczki Promise dla IndexedDB. Najpierw zaimportuj go do usługi js/main.js:

import { openDB } from 'idb';

Następnie dodaj ten kod konfiguracji na początku detektora zdarzeń DOMContentLoaded:

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

Wyjaśnienie

W tym przypadku tworzona jest baza danych IndexedDB o nazwie settings-store. Jego wersja jest inicjowana jako 1, a inicjowanie odbywa się za pomocą magazynu obiektów o nazwie settings. Jest to najbardziej podstawowy rodzaj magazynu obiektów, czyli proste pary klucz-wartość, ale w razie potrzeby można tworzyć bardziej złożone magazyny obiektów. Bez zainicjowania magazynu obiektów nie będzie gdzie umieszczać danych, więc pominięcie tego kroku byłoby jak utworzenie bazy danych bez tabel.

4. Zapisywanie stanu edytora po aktualizacji

Po zainicjowaniu bazy danych możesz zapisać w niej treści. Edytor udostępnia metodę onUpdate, która umożliwia przekazanie funkcji, która ma być wywoływana za każdym razem, gdy treść w edytorze zostanie zaktualizowana. To idealne miejsce, aby wprowadzić zmiany w bazie danych. Aby to zrobić, dodaj ten kod tuż przed deklaracją defaultText w pliku js/main.js:

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

Wyjaśnienie

db to wcześniej otwarta baza danych IndexedDB. Metoda put umożliwia tworzenie lub aktualizowanie wpisów w magazynie obiektów w tej bazie danych. Pierwszy argument to magazyn obiektów w bazie danych, którego należy użyć, drugi argument to wartość do zapisania, a trzeci argument to klucz, pod którym należy zapisać wartość, jeśli nie jest to oczywiste na podstawie wartości (w tym przypadku nie jest, ponieważ nasza baza danych nie zawiera określonych kluczy). Ponieważ jest asynchroniczna, jest opakowana w async/await.

5. Pobieranie stanu podczas wczytywania

Aby odzyskać pracę użytkownika, która jest w toku, należy ją wczytać podczas wczytywania edytora. Edytor udostępnia setContent metodę, która umożliwia ustawienie treści. Obecnie służy do ustawiania wartości defaultText. Zaktualizuj go w ten sposób, aby zamiast tego wczytać poprzednią pracę użytkownika:

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

Wyjaśnienie

Zamiast ustawiać edytor na wartość defaultText, próbuje teraz pobrać klucz content z magazynu obiektów settings w bazie danych settings-store IndexedDB. Jeśli ta wartość istnieje, jest używana. W przeciwnym razie używany jest tekst domyślny.

6. Ustawianie i pobieranie stanu trybu nocnego

Teraz, gdy znasz już IndexedDB, dodaj ten kod na końcu pliku js/main.js i zaktualizuj go, aby zapisywać preferencje użytkownika dotyczące trybu nocnego, gdy się zmienią, oraz wczytywać te preferencje podczas inicjowania trybu nocnego.

// 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. Gratulacje!

Wiesz już, jak zapisywać i wczytywać dane z magazynu obiektów w IndexedDB.

Kolejne laboratorium w tej serii to Od karty do paska zadań.