在我的网站上:
我想使用IndexedDB(通过Dexie)作为浏览器内缓存,这样他们每次查看地图时都不需要重新下载完整的Activity集。我以前从未使用过IndexedDB,所以我不知道自己是在做傻事还是在忽略任何边缘情况。
以下是我认为总体过程的概括描述:
在所有这些方面,我们需要专注于该用户。一个人可能查看许多人的页面,因此在IndexedDB中拥有许多人的数据的副本。因此,对服务器和IndexedDB的查询需要知道所引用的用户ID。
这是我决定做的英语版本:
putItemsFromIndexeddbOnMap
(如下所述)putItemsFromIndexeddbOnMap
对于putItemsFromIndexeddbOnMap:
下面是执行我上面解释的JavaScript代码(带有一些ERB,因为此JavaScript嵌入在Rails视图中):
var db = new Dexie("db_name");
db.version(1).stores({ activities: "id,user_id" });
db.open();
// get this user's activity IDs from the server
fetch('/users/' + <%= @user.id %> + '/activity_ids.json', { credentials: 'same-origin' }
).then(response => { return response.json() }
).then(activityIdsJson => {
// remove items from IndexedDB for this user that are not in activityIdsJson
// this keeps data that was deleted in the site from sticking around in IndexedDB
db.activities
.where('id')
.noneOf(activityIdsJson)
.and(function(item) { return item.user_id === <%= @user.id %> })
.keys()
.then(removeActivityIds => {
db.activities.bulkDelete(removeActivityIds);
});
// get this user's existing activity IDs out of IndexedDB
db.activities.where({user_id: <%= @user.id %>}).primaryKeys(function(primaryKeys) {
// filter out the activity IDs that are already in IndexedDB
var neededIds = activityIdsJson.filter((id) => !primaryKeys.includes(id));
if(Array.isArray(neededIds) && neededIds.length === 0) {
// we do not need to request any new data so query IndexedDB directly
putItemsFromIndexeddbOnMap();
} else if(Array.isArray(neededIds)) {
if(neededIds.equals(activityIdsJson)) {
// we need all data so do not pass the `only` param
neededIds = [];
}
// get new data (encoded_polylines for display on the map)
fetch('/users/' + <%= @user.id %> + '/encoded_polylines.json?only=' + neededIds, { credentials: 'same-origin' }
).then(response => { return response.json() }
).then(newEncodedPolylinesJson => {
// store the new encoded_polylines in IndexedDB
db.activities.bulkPut(newEncodedPolylinesJson).then(_unused => {
// pull all encoded_polylines out of IndexedDB
putItemsFromIndexeddbOnMap();
});
});
}
});
});
function putItemsFromIndexeddbOnMap() {
var featureCollection = [];
db.activities.where({user_id: <%= @user.id %>}).each(activity => {
featureCollection.push({
type: 'Feature',
geometry: polyline.toGeoJSON(activity['encoded_polyline'])
});
}).then(function() {
// if there are any polylines, add them to the map
if(featureCollection.length > 0) {
if(map.isStyleLoaded()) {
// map has fully loaded so add polylines to the map
addPolylineLayer(featureCollection);
} else {
// map is still loading, so wait for that to complete
map.on('style.load', addPolylineLayer(featureCollection));
}
}
}).catch(error => {
console.error(error.stack || error);
});
}
function addPolylineLayer(data) {
map.addSource('polylineCollection', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: data
}
});
map.addLayer({
id: 'polylineCollection',
type: 'line',
source: 'polylineCollection'
});
}
...我做对了吗?