Транзакция находит только 1-е хранилище объектов, созданное после инициализации IndexedDB с двумя хранилищами объектов - PullRequest
0 голосов
/ 11 апреля 2019

Я нашел несколько сообщений, в которых спрашивалось, можно ли и как создать несколько хранилищ объектов в одной базе данных IndexedDB. Это не совсем мои проблемы, я думаю. Я создал 2 хранилища объектов в одном событии onupgradeneeded и вижу оба хранилища в консоли разработчика Google Chrome. Так что я думаю, что это работает.

В одном хранилище объектов хранятся тренировки, другие упражнения ссылаются на тренировки по идентификатору (я пытался объединить их в одном хранилище объектов, но это было слишком хлопотно при обновлении информации). Когда я пытаюсь получить тренировку из 1-го хранилища объектов и соответствующие упражнения из 2-го хранилища объектов, приложение больше не может найти хранилище 2-х объектов. Кажется, доступен только 1-й магазин объектов.

Надеемся, что следующий код лучше объясняет проблему:

db.service.ts

Инициализация базы данных:

private db: IDBDatabase;

constructor() { }

public init(): Promise<void> {
    if(this.db) {
        this.db.close();
    }
    return new Promise(resolve => {
        const req = indexedDB.open('workoutsDB', 1);
        req.onupgradeneeded = e => {
            const db = (e.target as any).result;
            const workouts = db.createObjectStore(
                'workouts', {keyPath: 'id'});
            workouts.put({id: '1', name: '5x5'});
            const exercises = db.createObjectStore(
                'exercises', {keyPath: 'id'});
            exercises.put({id: '1', workout: '1', name: 'Squats'});
            exercises.put({id: '2', workout: '1', name: 'Bench presses'});
        }
        req.onsuccess = e => {
            this.db = (e.target as any).result;
            resolve();
        }
    });
}

Получить тренировку:

public getWorkout(id): Promise<Workout> {
    return new Promise<Workout>(resolve => {
        var tx = this.db.transaction('workoutsDB', 'readwrite');
        var store = tx.objectStore('workouts');  // <= THIS WORKS!!!
    });
}

Получить упражнения на тренировку:

public getExercises(workoutId): Promise<Exercise[]> {
    return new Promise<Exercise[]>(resolve => {
        var tx = this.db.transaction('workoutsDB', 'readwrite');
        var store = tx.objectStore('exercises'); // <= ERROR!!!
    });
}

Функции getWorkout(id) и getExercises(workoutId) вызываются со страницы Ionic следующим образом:

workout.page.ts

workout: Workout;
exercises: Exercises[] = [];

constructor(private db: DbService) { }

ngOnInit() {
    var id = this.route.snapshot.paramMap.get('id');
    this.db.init().then(() => getWorkout(id));
}

getWorkout(id) {
    this.db.getWorkout(id).then(workout => {
        this.workout = workout;
        this.db.getExercises(id).then(exercises => {
            this.exercises = exercises;
        });
    });
}

Я не уверен, что я делаю неправильно. Очевидно, что выполнение упражнений требует, чтобы я ПЕРВЫЙ получил соответствующую тренировку. Я подумал, что, возможно, существует конфликт между различными транзакциями или чем-то еще, но мне не удается точно определить проблему.

Любая помощь будет принята с благодарностью!

1 Ответ

2 голосов
/ 11 апреля 2019

Первый аргумент this.db.transaction неверен. Это должен быть массив имен всех хранилищ объектов, которые вы будете использовать в транзакции (или, если это просто хранилище одного объекта, это может быть строка, содержащая только это имя). Вместо этого вы помещаете туда название своей базы данных. Скорее всего, это ваша ошибка.

Если нет, то отредактируйте свое сообщение, добавив в него конкретное сообщение об ошибке, которое облегчит людям помощь. Или включите минимальный пример, который мы можем запустить, чтобы сами увидеть ошибку.

...