iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 18
1
Modern Web

30天走訪Progressive Web Apps(PWAs)系列 第 18

Day18-使用idb實作IndexedDB

  • 分享至 

  • xImage
  •  

用途

用來儲存資料到用戶端的瀏覽器。IndexedDB適合用來儲存大量非結構式的資料。

  • 非結構式的意思就是不限定格式,使用起來就像javascript中的object
  • Key-Value資料庫,IndexedDB存取資料的方式,是透過Key來讀取Value
  • 非同步的方式存取
  • 一個App只有一個資料庫
  • 基於交易性質的資料庫模型,再IndexedDB上進行的操作都是以Transaction(交易)的方式執行,假如存取過程中,有一個動作失敗,則整筆交易會取消,不會只存入一半的資料,防止資料不完全。

使用度

再支援上還不錯,大部分的瀏覽器都已經支援使用
https://ithelp.ithome.com.tw/upload/images/20180104/20103808iTOEmO5jJM.png

以Promise實作的IndexedDB套件

idb.js

Github: https://github.com/jakearchibald/idb

今天就用這個套件,來為專案加入IndexedDB的功能。

Step1: 下載idb.js,並放入js資料夾

https://ithelp.ithome.com.tw/upload/images/20180105/20103808v1k3efsWKP.png

index.html首頁中,引入idb.js檔案。

<script src="./src/js/idb.js"></script>   

但在DOM載入idb.js的檔案,'在service worker中是無法使用的(它無法直接操作DOM),但可以透過import的方式。

Step2: import API 到 Service Worker

importScripts('/src/js/idb.js');

importScripts()可以匯入相同網域的程式碼與函式庫。

Step3:使用open創建/開啟資料庫

idb.open(name, version, upgradeCallback)

name: DB名稱
version: DB版本
upgradeCallback: 假如版本比現在的新會呼叫callback

var dbPromise = idb.open('articles', 1, function(db){
    if(!db.objectStoreNames.contains('article'))
        db.createObjectStore('article', {keyPath: 'id'});
})

剛剛import idb.js後,接著建立一個articles的資料庫,假如資料表中沒有article的物件,就建立該物件,並以id當唯一的key值。

接著要去哪存入資料呢?
還記得前面我們使用Firebase來抓取文章嗎?
因此,我們要去改fetch事件,假如請求是firebase上的文章網址,我們就將文章存入IndexedDB中。

Step4: 修改fetch事件,存文章到IndexedDB

self.addEventListener('fetch', function(event){
    var url = 'https://days-pwas-practice.firebaseio.com/article.json';
    if(-1 < event.request.url.indexOf(url)){
        event.respondWith(  
            fetch(event.request)
                .then(function(response){
                    var copyRes = response.clone();
                    copyRes.json()
                        .then(function(data){
                            for(var key in data){
                                dbPromise
                                    .then(function(db){
                                        var transaction = db.transaction('article', 'readwrite');
                                        var article = transaction.objectStore('article');
                                        article.put(data[key]);
                                        return transaction.complete;
                                    })
                            }
                        })
                })
        );
    } else{
        ...
    }
});

Url是文章時,將請求clone(資源只能使用一次)後轉成json格式方存讀取,接著直接看到dbPromise是上面命名articles資料庫。
接著使用foreach將每筆資料丟入dbPromise(任意命名),transaction建立交易,並指定要丟入的資料表(ObjectStore),並設定可以讀寫。
put將資料存入,並回傳complete完成交易。

結果

  1. Application中,選擇Clear Storage,並點Clear Site,清除網站的紀錄。

  2. 按F5,並看Application,左邊側邊攔的IndexedDB
    https://ithelp.ithome.com.tw/upload/images/20180105/20103808HktmYVeLgv.png
    可以看到有articles資料庫,底下有article資料表,但是沒有任何資料。
    那是因為還沒觸發fetch

  3. 再一次F5重整網頁
    https://ithelp.ithome.com.tw/upload/images/20180105/20103808Qa7YSsUuBG.png
    看向右邊攔,發現我們成功將文章內容存入IndexedDB囉~/images/emoticon/emoticon42.gif


上一篇
Day17-動態取得資料(Daynamic Data之使用Firebase實作)
下一篇
Day19-IndexedDB之抽成共用檔案
系列文
30天走訪Progressive Web Apps(PWAs)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言