html离线存储之indexdDB 关于Cannot read property 'transaction' of undefined的问题(二)

IndexedDB标准是HTML5官方认可的本地数据库解决方案。而webSQL已经被w3c抛弃了。

这里我主要说下我遇到的问题,这两天才开始捣鼓这一块,想边学边写好一些接口,方便日后使用参考。但在写插入功能的时候卡住了。


我已经写了创建数据库的接口,并执行正常

//新建或打开数据库,第一次创建或更改版本时建表
//dbname:数据库名;version:版本号;storeName:仓库名;key:索引;increment:是否自增
function initIndexdDB(dbname,version,storeName,key,increment=false){
	var indexdDB = window.indexdDB||window.webkitIndexdDB||window.mozIndexdDB||window.msIndexdDB;
	var request = indexedDB.open(dbname, version);
	// var database=null;
	request.onsuccess = function(event) {
        console.log("创建/打开数据库成功。");
 
        //让数据库 可在任何地方访问
        database = request.result;
        //console.log("init"+database);

    };
    request.onerror = function (event) {
        console.log("发生错误:" + request.error);
    };
    request.onupgradeneeded = function(event) {
        alert("第一次创建数据库或者更新数据库。");
        //alert("数据库老版本为:" + event.oldVersion + " 更新后新版本为:" + event.newVersion)
    	database = request.result;
    	if(!increment)
    		var objectStore = database.createObjectStore(storeName, { keyPath: key }); 
    	else
    		var objectStore = database.createObjectStore(storeName, { keyPath: key ,autoIncrement: true}); 
    };
}

上面的接口可以用于打开已有数据库,创建数据库不建表或者并建表,打开指定数据库并建表。

本人在向已有数据库中建表这里,饶了不少圈子,这里说下,避免刚入坑者少踩坑,关键是理解好onupgradeneeded,它是在初次创建或者版本号发生更改的时候会被触发的时候执行,而建表的操作是放在这里面执行的,因为只要数据库的版本号没变,就可以算是表示数据库未发生变化,自然是无法在别处新建表的


接着说下又一个坑点,就是插入数据了,我写的接口是这样的
//增加记录
//objectStore:仓库(表)名,method(操作方式),objectData(插入的对象)
function addRecord(objectStore,method,objectData) {
	// console.log(database); 
	var transaction = database.transaction([objectStore], method);
	var objectStore = transaction.objectStore(objectStore);
	var request = objectStore.put(objectData);
	request.onerror = function(event) {
		console.log("发生错误:" + request.error);
	};
	request.onsuccess = function(event) {
		console.log("添加成功");
	}; 
}
其中database为打开的数据库对象,为全局变量,为什么不能将其设置为参数呢,我开始就是这么干的,然后在控制台就一直出现文章标题中的Cannot read property 'transaction' of undefined,百度了下只在StackOverflow中看到有个在解释的,大体上说的是indexdDB异步执行的原因,我自己也不是很理解这块,就各种console.log(),发现当将其设置为参数时,即使database为全局变量,且在initIndexdDB中已经将其赋值为数据库对象,但console.log的结果仍然是null

html离线存储之indexdDB 关于Cannot read property 'transaction' of undefined的问题(二)_第1张图片
如上图所示,database为null,自然后面的插入数据操作会失败,但从上图也可以看出问题得一些端倪,控制台上是先执行了console.log(),后才打开了数据库并赋值给了database,这里也看出indexdDB是异步执行的

所以下图这样效果就是对的了

html离线存储之indexdDB 关于Cannot read property 'transaction' of undefined的问题(二)_第2张图片

我这里因为都是控制台操作,可以一步步来,当把一组操作代码写好一起执行时就要格外注意这里了,代码执行速度很快还来不及获取到异步赋值的 database。理解好这个插入数据就不难了

html离线存储之indexdDB 关于Cannot read property 'transaction' of undefined的问题(二)_第3张图片

你可能感兴趣的:(html)