在上一篇,介紹一下漸進式 Web App(離線) - Part 1的文章中,咱們討論了典型的pwa應該是什麼樣子的而且同時也介紹了 server worker。到目前爲止,咱們已經緩存了應用殼。在 index.html
和latet.html
頁面中,咱們的應用已經實現了離線加載緩存數據。在重複訪問時,它們的加載速度更快。在本教程第一部分的結尾,咱們可以離線加載latest.html
,但在用戶離線時沒法顯示得到動態數據。此次學習咱們將:html
latest
頁面緩存 app的數據localStorage
去存儲 app 的數據在構建PWA時,須要考慮各類存儲機制:git
indexDB在瀏覽器的兼容性github
Cache API:這是存儲URL地址資源的最佳選擇。和Service worker配合是很是好滴。web
PouchDB:是CouchDB的開源JavaScript數據庫。它使應用程序可以在本地存儲數據,離線,而後同步與CouchDB和兼容的服務器應用程序時從新上線,保持用戶數據同步,無論他們下一次在哪裏登陸。PouchDB支持全部現代瀏覽器,使用IndexedDB引擎失敗的話就降級到WebSQL,對Firefox 29+ (包括 Firefox OS and Firefox for Android), Chrome 30+, Safari 5+, Internet Explorer 10+, Opera 21+, Android 4.0+, iOS 7.1+ 和 Windows Phone 8+等等都是兼容的。數據庫
Web Storage 例如 localStorage:它是同步的,是阻止DOM加載的,在瀏覽器中最多使用5MB, 它有簡單的 api去操做存儲鍵值對數據。apache
Web Storage 的瀏覽器兼容表npm
根據PouchDB的維護者 Nolan Lawson說,在使用數據庫時,最好問本身這些問題:json
您能夠查看考慮如何選擇數據庫,以便更全面地瞭解主題內容。api
在咱們的 web app 中,咱們將用localStorage
,因爲我在本教程前面強調的侷限性,我建議你不要在生產環境中使用localStorage
。咱們正在構建的應用程序很是簡單,因此是使用了localStorage
。瀏覽器
打開你的js/latest.js
文件,咱們更新fetchCommits
方法去存儲從Github API
拉取的數據,存儲在localStorage
。代碼以下:
function fetchCommits() {
var url = 'https://api.github.com/repos/unicodeveloper/resources-i-like/commits';
fetch(url)
.then(function(fetchResponse){
return fetchResponse.json();
})
.then(function(response) {
console.log("Response from Github", response);
var commitData = {};
for (var i = 0; i < posData.length; i++) {
commitData[posData[i]] = {
message: response[i].commit.message,
author: response[i].commit.author.name,
time: response[i].commit.author.date,
link: response[i].html_url
};
}
localStorage.setItem('commitData', JSON.stringify(commitData));
for (var i = 0; i < commitContainer.length; i++) {
container.querySelector("" + commitContainer[i]).innerHTML =
"<h4> Message: " + response[i].commit.message + "</h4>" +
"<h4> Author: " + response[i].commit.author.name + "</h4>" +
"<h4> Time committed: " + (new Date(response[i].commit.author.date)).toUTCString() + "</h4>" +
"<h4>" + "<a href='" + response[i].html_url + "'>Click me to see more!</a>" + "</h4>";
}
app.spinner.setAttribute('hidden', true); // hide spinner
})
.catch(function (error) {
console.error(error);
});
};
複製代碼
上面有這段代碼,在第一頁加載的時候,這些提交的數據就存儲到localStorage
了,如今咱們寫另一個函數去渲染這些localStorage
的數據。代碼以下:
// Get the commits Data from the Web Storage
function fetchCommitsFromLocalStorage(data) {
var localData = JSON.parse(data);
app.spinner.setAttribute('hidden', true); //hide spinner
for (var i = 0; i < commitContainer.length; i++) {
container.querySelector("" + commitContainer[i]).innerHTML =
"<h4> Message: " + localData[posData[i]].message + "</h4>" +
"<h4> Author: " + localData[posData[i]].author + "</h4>" +
"<h4> Time committed: " + (new Date(localData[posData[i]].time)).toUTCString() + "</h4>" +
"<h4>" + "<a href='" + localData[posData[i]].link + "'>Click me to see more!</a>" + "</h4>";
}
};
複製代碼
這段代碼將數據從本地存儲並將其渲染 dom 節點。
如今咱們須要知道,什麼條件去調用fetchCommits
函數和fetchCommitsFromLocalStorage
函數。
js/latest.js
代碼以下
(function() {
'use strict';
var app = {
spinner: document.querySelector('.loader')
};
var container = document.querySelector('.container');
var commitContainer = ['.first', '.second', '.third', '.fourth', '.fifth'];
var posData = ['first', 'second', 'third', 'fourth', 'fifth'];
// Check that localStorage is both supported and available
function storageAvailable(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return false;
}
}
// Get Commit Data from Github API
function fetchCommits() {
var url = 'https://api.github.com/repos/unicodeveloper/resources-i-like/commits';
fetch(url)
.then(function(fetchResponse){
return fetchResponse.json();
})
.then(function(response) {
console.log("Response from Github", response);
var commitData = {};
for (var i = 0; i < posData.length; i++) {
commitData[posData[i]] = {
message: response[i].commit.message,
author: response[i].commit.author.name,
time: response[i].commit.author.date,
link: response[i].html_url
};
}
localStorage.setItem('commitData', JSON.stringify(commitData));
for (var i = 0; i < commitContainer.length; i++) {
container.querySelector("" + commitContainer[i]).innerHTML =
"<h4> Message: " + response[i].commit.message + "</h4>" +
"<h4> Author: " + response[i].commit.author.name + "</h4>" +
"<h4> Time committed: " + (new Date(response[i].commit.author.date)).toUTCString() + "</h4>" +
"<h4>" + "<a href='" + response[i].html_url + "'>Click me to see more!</a>" + "</h4>";
}
app.spinner.setAttribute('hidden', true); // hide spinner
})
.catch(function (error) {
console.error(error);
});
};
// Get the commits Data from the Web Storage
function fetchCommitsFromLocalStorage(data) {
var localData = JSON.parse(data);
app.spinner.setAttribute('hidden', true); //hide spinner
for (var i = 0; i < commitContainer.length; i++) {
container.querySelector("" + commitContainer[i]).innerHTML =
"<h4> Message: " + localData[posData[i]].message + "</h4>" +
"<h4> Author: " + localData[posData[i]].author + "</h4>" +
"<h4> Time committed: " + (new Date(localData[posData[i]].time)).toUTCString() + "</h4>" +
"<h4>" + "<a href='" + localData[posData[i]].link + "'>Click me to see more!</a>" + "</h4>";
}
};
if (storageAvailable('localStorage')) {
if (localStorage.getItem('commitData') === null) {
/* The user is using the app for the first time, or the user has not
* saved any commit data, so show the user some fake data.
*/
fetchCommits();
console.log("Fetch from API");
} else {
fetchCommitsFromLocalStorage(localStorage.getItem('commitData'));
console.log("Fetch from Local Storage");
}
}
else {
toast("We can't cache your app data yet..");
}
})();
複製代碼
在上面的代碼片段,咱們正在檢查瀏覽器是否支持本地存儲,若是它支持,咱們繼續檢查是否已經緩存了提交數據。若是沒有被緩存,咱們將請求數據,顯示到頁面上而且緩存請求的數據。
如今,重新刷新一遍瀏覽器,確保你作了一個清晰的緩存,強制刷新,不然咱們不會看到咱們的代碼更改的結果。
如今,離線並加載最新頁面。將發生了什麼事呢?
Yaaay!!! 它加載數據沒有任何問題。
查看DevTools
,你間看到數據已經被緩存到localStorage
當用戶離線時,看看它加載的速度!!!
如今,咱們能夠當即從本地存儲獲取數據。可是咱們如何得到最新的數據?當用戶在線時,咱們須要一種仍然得到新數據的方法。
so easy, 讓咱們添加一個刷新按鈕,觸發一個請求到GitHub得到的最新數據。
打開latest.html
文件,而且添加一個刷新按鈕到<header>
標籤
<button id="butRefresh" class="headerButton" aria-label="Refresh"></button>
複製代碼
添加的按鈕後<header>
標籤應該是這樣的:
<header>
<span class="header__icon">
<svg class="menu__icon no--select" width="24px" height="24px" viewBox="0 0 48 48" fill="#fff">
<path d="M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z"></path>
</svg>
</span>
<span class="header__title no--select">PWA - Commits</span>
<button id="butRefresh" class="headerButton" aria-label="Refresh"></button>
</header>
複製代碼
最後,讓咱們在按鈕上附加一個單擊事件並添加功能。打開js/latest.js
而且添加以下代碼:
document.getElementById('butRefresh').addEventListener('click', function() {
// Get fresh, updated data from GitHub whenever you are clicked
toast('Fetching latest data...');
fetchCommits();
console.log("Getting fresh data!!!");
});
複製代碼
清除緩存並從新加載。如今,你的latest.html
頁面看起來應該像這樣:
每當用戶須要最新數據時,他們只需單擊刷新按鈕便可。
附加:
點擊查看下面連接
上一篇: [譯]介紹一下漸進式 Web App(離線) - Part 1
若是有那個地方翻譯出錯或者失誤,請各位大神不吝賜教,小弟感激涕零
期待下一篇: 介紹一下漸進式 Web App(消息推送) - Part 3