Rychlý tip:Ukládejte data v prohlížeči pomocí IndexedDB

IndexedDB API vám poskytuje rychlé úložiště klíč/hodnota v prohlížeči. A je podporován ve více prohlížečích, než si myslíte (díky shimu to může fungovat i v těch starších). To znamená, že když nastane potřeba, máte způsob, jak uložit trvalou sbírku dat v prohlížeči uživatele, aniž byste museli být závislí na připojení k internetu. Špatnou zprávou je, že IndexedDB má velmi těžkopádné a podrobné API, které je obtížné používat. Naštěstí existuje malá knihovna, která může být obrovskou pomocí. Jmenuje se db.js a v tomto rychlém tipu vám ukážu, jak jej používat.

Jak používat db.js

IndexedDB hodně spoléhá na nastavení zpětných volání, naslouchání chybám a práci se spoustou dočasných proměnných. Db.js to před vámi skrývá a odhaluje lineárnější a snadno ovladatelné rozhraní, které by ocenil každý fanoušek jQuery. Knihovna dokonce používá stejný mechanismus odložených/příslibů jako jQuery. Pokud nevíte, co kterákoli z předchozích věcí, které jsem zmínil, znamenají, nebojte se, jakmile uvidíte nějaký kód, bude to jasnější.

Za tímto účelem vytvoříme malou demo aplikaci. Provede následující:

  • Nejprve definujte schéma nového úložiště klíč/hodnota spolu s číslem verze;
  • Pokuste se otevřít databázi, a pokud vše proběhlo v pořádku, pokračujte;
  • Nastavte posluchač událostí pro kliknutí na prvek „Přidat“. V těle posluchače vložíme záznam do databáze a zobrazíme položku na stránce;
  • Po kliknutí na položku smažte příslušný záznam z databáze a odstraňte jej ze stránky.

Kromě toho, že jsou tyto operace super rychlé, jsou také trvalé, takže když obnovíte stránku nebo zavřete prohlížeč, data tam budou stále. Ve skutečné aplikaci byste chtěli synchronizovat obsah úložiště IndexedDB se svým serverem, ale dnes to neuděláme.

Kodex

Prvním krokem je definovat schéma našeho úložiště dat. Na rozdíl od relačních databází, jako je MySQL, zde nemáme pojem tabulek s předdefinovanými sloupci a typy. IndexedDB může obsahovat libovolné objekty JavaScriptu v rámci jednoho úložiště dat. Jediným požadavkem v tomto kroku je volitelně vybrat pole id, ať už se má automaticky zvyšovat, a definovat nula nebo více indexů.

assets/js/script.js

// Use the db.js library, define a schema,
// and listen for events

db.open({
    name: 'database',
    version: 2,
    schema: {
        items: {
            key: {
                keyPath: 'id',
                autoIncrement: true
            },
            indexes: {
                color: { unique: false }
            }
        }
    }
})

Definování indexu sdělí IndexedDB, že by měla hledat tuto vlastnost v objektech, které vložíte do úložiště dat. Poté budete moci načíst a seřadit všechny objekty, které mají tento index. Ve výše uvedeném příkladu definuji index pro vlastnost color a říkám db.js, že nechci, aby byl jedinečný (pokud by byl, byl bych schopen uložit pouze jeden objekt s touto barvou). Nepoužívám tento index přímo v aplikaci, ale rozhodl jsem se jej přesto zahrnout, abych vám ukázal, jak se to dělá. Pokud si přejete aktualizovat schéma, budete muset také zvýšit číslo verze.

Stejně jako u všeho ostatního je otevření databáze v IndexedDB asynchronní a může selhat v řadě případů (prohlížeč to nepodporuje, číslo verze je špatné nebo je uživatel v režimu inkognito). Musíme předat zpětné volání done() Metoda po otevření databáze, abychom si byli jisti, že vše proběhlo úspěšně. Získáme také odkaz na objekt serveru, který potřebujeme ke spouštění dotazů.

db.open({
    name: 'database',
    version: 2,
    schema: {
        items: {
            key: {
                keyPath: 'id',
                autoIncrement: true
            },
            indexes: {
                color: { unique: false }
            }
        }
    }
}).done(function(server){

    // The database was successfully opened. We can
    // run transactions using the server varaible

    // Listen for the document ready event, as we will
    // be working with the dom

    $(function() {

        // Cache some selectors

        var add = $('#add'),
            items = $('#items');

        var colors = ['blue', 'green', 'yellow', 'pink'];

        // On dom.ready, select all items and update the #items ul
        server.items.query().filter().execute().done(function(results){

            if(!results){
                return;
            }

            $.each(results, function(){
                createItem(this);
            });

        });

        // Listen for clicks on the add button
        add.click(function(){

            var item = {
                text: (new Date()).toTimeString(),
                color: colors[ Math.floor( Math.random()*colors.length )]
            };

            server.items.add(item).done(function(){
                createItem(item);
            });

            // If you wish to update an item:
            // server.items.update({id:123, color:'pink', text:'asdf'});
        });

        // When an item is clicked, remove it from the database.
        $('#items').on('click', 'li:not(#add)', function(){
            var item = $(this);
            server.items.remove( item.data('id') ).done(function(){
                item.fadeOut();
            });
        });

        function createItem(item){
            var tmp = $('<li><p></p></li>');

            tmp.addClass( item.color )
                .data('id', item.id)
                .find('p').text( item.text );

            items.prepend(tmp);
        }

    });

}).fail(function(error){

    console.error("An error occured: ", error);

});

Uvnitř zpětného volání:

  • poslouchejte událost document.ready;
  • vybrat všechny existující položky z databáze a zobrazit je na stránce;
  • poslouchat kliknutí na prvek „Přidat“ a vytvářet nové položky;
  • poslouchat kliknutí na samotné položky a odstranit je z databáze;
  • definujte funkci zpětného volání pro vytváření položek a jejich přidávání na stránku.

V případě selhání zaznamenáme pouze zjištěnou chybu do konzoly. Tímto je náš jednoduchý příklad IndexedDB dokončen!

Další informace a příklady použití db.js najdete v tomto blogovém příspěvku vývojáře nebo si přečtěte zdrojový kód.