Получить значения Dexie без использования toArray()

У меня есть следующий код:

(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');
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
182
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример показывает, что вы меняете первичный ключ, который не поддерживается:

Первое объявление указывает таблицу «usersData» с исходящими первичными ключами:

db.version(1).stores({
    usersData: ""
});

Затем в обратном вызове setTimout вы повторно объявляете его с помощью:

db2.version(1).stores({
    usersData: "userSettings,savedGames"
});

... это означает, что вам нужен входящий первичный ключ из свойства «userSettings» и индекс для свойства «savedGames».

Здесь три ошибки:

  1. Вы не можете изменить объявление без увеличения номера версии, что здесь не делается.
  2. Вы не можете изменить первичный ключ в существующей базе данных.
  3. Обещания не перехватываются, поэтому вы не видите ошибок.

Похоже, что вы действительно намереваетесь использовать 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);

Очень понятно и полезно, спасибо большое :)

Andrew Howard 22.12.2020 14:31

Другие вопросы по теме