У меня есть следующий код:
(function () {
var gameDataLocalStorageName = "myTest3";
var defaultUserSettings = {
volumes: {
musicVolume: 0.3,
sfxVolume: 0.5,
voicesVolume: 1
}
};
var savedGames = [
{
screenshot: "data uri here",
day: "1",
month: "1",
year: "1",
time: "1",
gameData: {
fonts: [{
id: 123,
name: "Arial"
}],
globalSpeeches: {
anotherVal: "something"
}
}
}
];
console.info(gameDataLocalStorageName);
console.info(defaultUserSettings);
console.info(savedGames);
/* Create db START */
var db = new Dexie(gameDataLocalStorageName);
db.version(1).stores({
usersData: ""
});
db.usersData.put(defaultUserSettings, 'userSettings');
db.usersData.put(savedGames, 'savedGames');
}());
/* Create db END */
/* Recall db START */
setTimeout(function(){
var db2 = new Dexie("myTest3");
db2.version(1).stores({
usersData: "userSettings,savedGames"
});
db2.usersData.toArray().then(function (results) {
console.info("User settings is: ", results[1]);
console.info("Saved games is: ", results[0]);
});
}, 3000);
Который отлично работает. Однако как я могу снова получить данные без необходимости рендеринга в виде массива toArray()
. В настоящее время, чтобы получить их, мне нужно жестко закодировать results[0]
и results[1]
, что также не в том порядке, в котором я ввел их в БД.
В идеале я хочу сделать что-то вроде:
db2.get('usersData.userSettings');
db2.get('usersData.savedGames');
Пример показывает, что вы меняете первичный ключ, который не поддерживается:
Первое объявление указывает таблицу «usersData» с исходящими первичными ключами:
db.version(1).stores({
usersData: ""
});
Затем в обратном вызове setTimout вы повторно объявляете его с помощью:
db2.version(1).stores({
usersData: "userSettings,savedGames"
});
... это означает, что вам нужен входящий первичный ключ из свойства «userSettings» и индекс для свойства «savedGames».
Здесь три ошибки:
Похоже, что вы действительно намереваетесь использовать Dexie в качестве хранилища ключей/значений, что совершенно нормально, но гораздо проще, чем показано в примере.
Если вы помещаете() (или добавляете()) значение, используя определенный ключ, вы получаете то же самое, используя get().
Если это так, попробуйте следующее:
db.version(1).stores({
usersData: "",
});
И не забывайте ловить промисы или ждать и делать попытки/поймать.
(async ()=>{
await db.usersData.put(defaultUserSettings, 'userSettings')
await db.usersData.put(savedGames, 'savedGames');
// Get using key:
const userSettings = await db.usersData.get('userSettings');
console.info("User settings is: ", userSettings);
const savedGames = await db.usersData.get('savedGames');
console.info("User settings is: ", savedGames);
})().catch(console.error);
Однако помещать целые массивы в качестве значений в хранилище ключей/значений не очень оптимально.
Может быть, есть только две таблицы «userSettings» и «savedGames», где каждая сохраненная игра будет отдельной строкой? Будете ли вы поддерживать нескольких пользователей или только одного пользователя? Если их несколько, вы можете добавить в свои таблицы индекс «userId».
Если это так, попробуйте следующее:
db.version(2).stores({
userSettings: "userId" // userId is primary key
savedGames: "++gameId, userId" // incremented id and userId is foreign key
});
(async ()=>{
await db.userSettings.put({...defaultUserSettings, userId: "fooUser"});
await db.savedGames.bulkPut(savedGames.map(game =>
({...game, userId: "fooUser"}));
// Get user settings:
const userSettings = await db.usersData.get('fooUser');
console.info("User settings is: ", userSettings);
const savedGames = await db.usersData.where({userId: "fooUser"}).toArray();
console.info("Saved games for fooUser are: ", savedGames);
})().catch(console.error);
Очень понятно и полезно, спасибо большое :)