我正在开发一个简单的Angular应用程序,我想在IndexedDB中存储一些数据。
我有一个在构造函数中初始化private db: IDBDatabase;
的服务:然而,当我试图在另一个方法调用中使用由构造函数初始化的DB时,这个DB从未被定义过。我知道这可能与异步调用、回调和承诺有关,但我不知道是什么...所以现在我能想到的唯一解决方案是调用
window.indexedDB.open("MyTestDatabase", 1);
每次
import {Injectable} from '@angular/core';
import {Directory, Bookmark} from "./models";
import {connectableObservableDescriptor} from "rxjs/internal/observable/ConnectableObservable";
@Injectable({
providedIn: 'root'
})
export class BookmarksService {
private db: IDBDatabase;
private directoriesStoreName = "directoreis";
private bookmarksStoreName = "bookmakrs";
constructor() {
console.log("Calling Bookmarks Service Constructor .... ");
if (!window.indexedDB) {
console.log("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.");
}
let openDBRequest: IDBOpenDBRequest = window.indexedDB.open("MyTestDatabase", 1);
console.log("Let's see if the DB will open .. ")
/**
* The only place where a data can be defined is onupgradeneeded callback !
* @param event
*/
openDBRequest.onupgradeneeded = (event: any) => {
console.log("onupgradeneeded fired");
this.db = event.target.result;
};
openDBRequest.onsuccess = (event: any) => {
console.log("seems that db is opened ! ");
console.log(event);
this.db = event.target.result;
this.db.onerror = x => {
console.log("An error occurred while working with DB! ");
}
};
openDBRequest.onerror = event => {
console.log("can't open IndexedDB");
console.log(event);
}
getAllChildDirs(parentId: number): Directory[] {
if (this.db) { // this is NEVER defined, why ?!
var os = this.db.transaction(this.directoriesStoreName).objectStore(this.directoriesStoreName);
var request = os.index("parent_id");
var dirs: Directory[] = [];
request.openCursor(IDBKeyRange.only(parentId)).onsuccess = (event: any) => {
var cursor = event.target.result;
if (cursor) {
// cursor.key is a name, like "Bill", and cursor.value is the whole object.
console.log("Name: " + cursor.key + ", SSN: " + cursor.value);
dirs.push(cursor.value);
cursor.continue();
}
};
return dirs;
}
}
}
然后我有一个这样的组件:
export class DirectoriesListComponent implements OnInit {
@Input() bookmarks: Bookmark[];
@Input() directories: Directory[];
isCollapsed = false;
common: CommonService;
bookmarksService: BookmarksService;
constructor(commons: CommonService, bookmarksService: BookmarksService) {
this.common = commons;
this.bookmarksService = bookmarksService;
}
ngOnInit(): void {
this.directories = this.bookmarksService.getAllRootDirs(); // ALWAYS returns empty array ?! becuase the db is never defined ...
this.bookmarks = this.bookmarksService.getBookmarks();
//listens on when button is clicked to collapse the menu !
this.common.dirsMenuCollapsed.subscribe(val => {
this.isCollapsed = val
})
}
1条答案
按热度按时间dced5bon1#
实际上,问题是你无法控制onsuccess函数何时被调用,因为它是一个回调函数,并且会在你无法控制的时候被执行。
无论您如何控制它,请查看以下内容:
大概是这样的:
当你返回一个承诺时,你应该在调用它时使用await: