indexeddb objectstore.add()keypath =' id'

时间:2016-10-11 08:47:50

标签: javascript key add indexeddb

我有一些对象存储,并在它们之间进行拆分。在初始安装chrome扩展时,我将数据添加到各种对象库,我想确保数据正确对齐。所以当安装过程中事情不同步时。 " keypath / id"将正确匹配的东西。没什么大不了的。

初始安装后会出现

问题。并添加另一条记录。 和" id"初始记录的/ keyPath / key显示id:1,id:2,id:3等等......

但是在初始安装后的记录。在将它添加到objectstore之前,我不再知道密钥是什么。是否有一个我缺少的代码片段,所以我可以创建一个对象并添加到objecstore,以及id,或者我搞砸了最初创建id:1并且应该使用类似keyPath:1或key:1或Primarykey :1?

我可以花很长时间,并使用一些承诺,

objectstore.add(object)
.then(objecstore.get(event.key) 
.then(objestore.put(key, {"id":key}) 

我注意记得上面的正确承诺代码。但是objectstore.add,然后一旦添加了密钥,然后.put({" id&#34 ;: key})来更新" id"已完成,是它的主旨。我试图阻止首先需要这样做。

有点像SQL这样的数据库,并且有2个主键,即数字,自动增量,并且在同一个表的各个方面完全相同。但在我的情况下,密钥更新," id"占用空间。并且不确定如何删除' id'从最初开始。或者一旦完成,如何保持密钥和' id'同步没有一堆额外的承诺。

在下面的代码中评论,试图找出答案。并没有成功,因为我自己搞清楚



    const ms_master = [{
//========================
//did i mess up here in creating id: and should of used like keypath:1?
//========================
      "id": 1,
      "baseurl": "www.example1.net",
      "prefix": "ex1",
      "name": "tryout1",
    }, {
      "id": 2,
      "baseurl": "www.something.com",
      "prefix": "so",
      "name": "some some",
    }, {
      "id": 3,
      "baseurl": "woops.org",
      "prefix": "woo",
      "name": "arghs",
    }]

    var db;
    var request = window.indexedDB.open("mystyle", 1);
    request.onerror = function(event) {
      console.log("error: ")
    };
    request.onsuccess = function(event) {
      db = event.target.result;
      console.log("success: " + db);
    };
    request.onupgradeneeded = function(event) {
        var db = event.target.result;
        if (!db.objectStoreNames.contains("ms_master")) {
//========================
//did i mess up here in creating the store?
//========================
          var objectStore = db.createObjectStore("ms_master", {
            keypath: "id",
            autoIncrement: true,
            unique: true
          });
          objectStore.createIndex("baseurl", "baseurl", {
            unique: false
          });
          objectStore.createIndex("prefix", "prefix", {
            unique: false
          });
          objectStore.createIndex("name", "name", {
            unique: false
          });
//========================
//seems to make no difference
//========================
          //objectStore.createIndex("id","id", { unique: true });
          for (var i in ms_master) {
            objectStore.add(ms_master[i]);
          }
//========================
//once added, should i do a objecstore.get and grab data, then do a objectstore.put that does not have 'id" in it?
//========================
        }

        $(document).ready(function() {
              document.getElementById('ms_table_add').addEventListener("click", ms_table_add);
            }

            function ms_table_add() {
              var db;
              var request = indexedDB.open('mystyle', 1);
              request.onsuccess = function(e) {
                db = e.target.result;
                var transaction = db.transaction('ms_master', "readwrite");
                var objectStore = transaction.objectStore('ms_master');
                var myobj = [
                  "id",
                  "name",
                  "prefix",
                  "baseurl"
                ];
                var myarray = {};
                for (var h = 0; h < myobj.length; h++) {
                  if (h == 0) {
//========================
//am i not getting the correct code to get id and keypath to sync up?
//========================
                    //{name: 'ms_master', keyPath: 'id'}
                    //myarray[myobj[h]] = 'id';
                  } else {
                    var temp = document.getElementById('ms_table_add_' + myobj[h]).value;
                    if (typeof temp !== "undefined" && temp !== null && temp !== "") {
                      myarray[myobj[h]] = temp;
                    }
                  }
                }
                objectStore.add(myarray);
//==============================
//trying to avoid extra promises to add, then get key, then update id here.
//==============================

                document.getElementById("ms_listings_master_add").innerHTML = "";
              }
            }

            function site_adding() {
              //function that builds up a html form / textareas / inputs and .innerhtml into 
              //<div id="ms_listings_master_add"></div>
            }
&#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <button id="site_adding">add a site</button>
    </br>
    <div id="ms_listings_master_add"></div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

您正在使用两个功能 - 内嵌键和键生成器。我将分别解释它们以及它们是如何构成的。

在线和外线密钥

内嵌键键值出现在记录本身中 - 带有keyPath的商店使用内联键。相比之下,外线密钥将密钥值分开。

var storeWithOutOfLineKeys = db.createObjectStore('s1');
storeWithOutOfLineKeys.put({name: 'alice'}, 1);

var storeWithInLineKeys = db.createObjectStore('s2', {keyPath: 'id'});
storeWithInLineKeys.put({name: 'bob', id: 1});

如果您没有为具有外线密钥的商店提供显式密钥,则对put()add()的调用将失败。如果执行使用内嵌键为商店提供显式密钥,则put()add()的调用将失败,如果记录不包含in-,则会失败行键值(例如,在上例中缺少id属性)

密钥生成器

当您指定autoIncrement: true时,您正在使用规范称为密钥生成器的内容。对于添加的每个记录,如果没有另外指定,则第一个将获得1,第二个2等。您可以通过查看put()的结果找出使用的密钥或add()请求,例如

var request = store.put({name: 'alice'});
request.onsuccess = function() {
  console.log('put got generated key: ' + request.result;
};

内联键和密钥生成器

使用密钥生成器时,add()put()的行为会发生变化:

密钥生成器和外线密钥:调用add()put()时无需传递显式密钥;如果省略,则使用生成的密钥:

var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
storeWithOutOfLineKeys.put({name: 'alice'});

如果传递了明确的密钥,则使用,覆盖以前的记录或添加新的记录。 (如果传递的密钥恰好是高于生成器值的数字,则生成器将设置为该数字。)

密钥生成器和内联密钥:调用add()put()时,无需在记录中指定密钥;如果省略,生成的密钥将被注入值。

var storeWithInLineKeys = db.createObjectStore('s2', {keyPath: 'id'});
storeWithInLineKeys.put({name: 'bob'}).onsuccess = function(e) {
  var id = e.target.result;
  storeWithInLineKeys.get(id).onsuccess = function(e) {
    console.log(JSON.stringify(e.target.result));
    // {"name": "bob", "id": 1}
  });
});

同样地,如果记录 包含键值,则将使用它。 (如果它的数字高于密钥生成器状态,则将调整密钥生成器。)

我相信最后一种情况与您的代码正在进行的操作相匹配 - 内联键和密钥生成器。您可以使用add()put()请求的结果来确定添加的密钥,并通过在记录中明确指定密钥来更新记录:

storeWithInLineKeys.put({name: 'eve', id: 1}); // overwrites old #1

答案 1 :(得分:0)

这就是我所寻找的((来自How do I specify key when adding records to objectStore w/ in IndexedDB?))和你的职位Joshua Bell。它点击了:)谢谢!

objectStore.add({name: "myData"}, 47);

我需要在下方进行重组,因此我可以删除“id”#39;本身完全,并且在上面的文字中仍然有关键符号#47。

const ms_master = [{
      "id": 1,
      "baseurl": "www.example1.net",
      "prefix": "ex1",
      "name": "tryout1",
    }, {
      "id": 2,
      "baseurl": "www.something.com",
      "prefix": "so",
      "name": "some some",
    }, {
      "id": 3,
      "baseurl": "woops.org",
      "prefix": "woo",
      "name": "arghs",
    }]

你的第一个例子

var storeWithOutOfLineKeys = db.createObjectStore('s1');
storeWithOutOfLineKeys.put({name: 'alice'}, 1);

你的第四个例子

var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
storeWithOutOfLineKeys.put({name: 'alice'});

新做...

var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
//for initial putting data into indexeddb (during install of chrome extension)
storeWithOutOfLineKeys.add({name: 'alice'}, 1);
//for adding data at a later time
storeWithOutOfLineKeys.add({name: 'alice'});
//for updating something...
storeWithOutOfLineKeys.put({name: 'alice'}, 1);
相关问题