Angularjs IndexedDB密钥生成器在put事务后重置
这个问题把我难住了 出于某种原因,indexedDB中的自动递增键生成器在使用put事务对现有对象执行和更新后重置,从而导致数据库中的数据被覆盖 对于我的应用程序,我正在为angularJS使用一个自行编写的IndexedDB服务,并实现了所有基本的CRUD函数。 我还可以补充一点,我是用离子框架开发的,尽管我怀疑这是罪魁祸首 考虑到该服务是一项正在进行的工作,我使用自动递增策略将对象存储的密钥路径默认为“id”。 然而,给定存储的索引由用户在特定对象中决定。 例如:Angularjs IndexedDB密钥生成器在put事务后重置,angularjs,ionic-framework,indexeddb,angularjs-service,Angularjs,Ionic Framework,Indexeddb,Angularjs Service,这个问题把我难住了 出于某种原因,indexedDB中的自动递增键生成器在使用put事务对现有对象执行和更新后重置,从而导致数据库中的数据被覆盖 对于我的应用程序,我正在为angularJS使用一个自行编写的IndexedDB服务,并实现了所有基本的CRUD函数。 我还可以补充一点,我是用离子框架开发的,尽管我怀疑这是罪魁祸首 考虑到该服务是一项正在进行的工作,我使用自动递增策略将对象存储的密钥路径默认为“id”。 然而,给定存储的索引由用户在特定对象中决定。 例如: dbHelper.obje
dbHelper.objectStores = [{'employees',
indices: [{indexName: 'name', isUnique: false},
{indexName: 'phone', isUnique: true}]}];
除非已经在数据库中创建,否则这将创建索引为“name”和“phone”的对象存储“employees”,其中“phone”必须是唯一的值,而“name”则不能
下面是openDB函数的实现。
请注意,dbHelper.objectStores应该是空的,因为在打开数据库之前由用户分配这些属性(否则为默认值)
以下是一些CRUD函数(有问题的函数):
最后,来自调用事务的控制器的代码。
这里的策略是,第一次持久化该项时,使用addItemToStore函数将其添加到db中,然后使用updateItem函数将其添加到db中。
第一次添加后,立即提取对象,以便使用数据库中指定的id继续处理该对象
$scope.updateTemplate = function() {
console.log('Saving..');
var onCompleteCallback = {};
if(!$scope.formTemplate.firstSave) {
onCompleteCallback = $scope.updateModel;
} else {
$scope.formTemplate.firstSave = false;
onCompleteCallback = $scope.setId;
}
$db.updateItem($scope.formTemplate, $scope.objectStore.name,
onCompleteCallback, $scope.dbError);
};
$scope.newItem = function() {
$db.addItemToStore($scope.formTemplate, $scope.objectStore.name,
$scope.setId, $scope.dbError);
};
$scope.setId = function() {
$db.findItemWithIndex(
{key: 'title',
value: $scope.formTemplate.title},
$scope.objectStore.name,
function(result) {
console.log(JSON.stringify(result));
$scope.formTemplate = result;
},
function(error) {
$scope.dbError(error);
});
}
就在这里,一切都会下地狱。
我添加了一个对象,返回到另一个视图,并在id=1的列表中找到它。
我添加了另一个对象,返回列表视图,它的id=2。
诸如此类
然后,在使用$scope.updateTemplate函数(该函数也像一个符咒一样工作)更新任何一个对象之后,事情变得有趣起来:
添加的下一个对象得到id=1,并完全删除先前的好的旧numero uno
下一个对象也会获得id,从而使它们替换现有的对象
这是什么原因造成的
为了进行测试,我在OS 10.10中使用Safari 8,并将其部署到带有KitKat 4.4.2的LGG2上。老实说,我略读了一下,但我发现,“Safari 8”-最新的iOS和Safari在IndexedDB上有严重的错误:在iOS9中,许多IndexedDB错误已经修复,但不是全部。我们目前正在iOS9 Beta 2上进行测试,您发现的这个特定错误尚未修复 我们能够通过在对象存储上不使用自动增量来解决这个问题。我们只需手动找到最大键值并增加它 插入对象的方式如下所示:
var store = db.transaction([entity], "readwrite").objectStore(entity);
store.openCursor(null, "prev").onsuccess = function (event) {
var maxKey = event.target.result.key || 0;
object.id = maxKey + 1;
store.add(object);
}
我建议您将问题简化为重现问题所需的相关代码/信息。这样做的机会是,你会发现你自己的问题。在任何情况下,添加plunker/JSFIDLE都有助于其他人帮助您调试代码。你最终做了什么来解决这个问题?我们在想,也许我们应该停止使用自动增量,只创建我们自己的关键点。
$scope.updateTemplate = function() {
console.log('Saving..');
var onCompleteCallback = {};
if(!$scope.formTemplate.firstSave) {
onCompleteCallback = $scope.updateModel;
} else {
$scope.formTemplate.firstSave = false;
onCompleteCallback = $scope.setId;
}
$db.updateItem($scope.formTemplate, $scope.objectStore.name,
onCompleteCallback, $scope.dbError);
};
$scope.newItem = function() {
$db.addItemToStore($scope.formTemplate, $scope.objectStore.name,
$scope.setId, $scope.dbError);
};
$scope.setId = function() {
$db.findItemWithIndex(
{key: 'title',
value: $scope.formTemplate.title},
$scope.objectStore.name,
function(result) {
console.log(JSON.stringify(result));
$scope.formTemplate = result;
},
function(error) {
$scope.dbError(error);
});
}
var store = db.transaction([entity], "readwrite").objectStore(entity);
store.openCursor(null, "prev").onsuccess = function (event) {
var maxKey = event.target.result.key || 0;
object.id = maxKey + 1;
store.add(object);
}