无法在“ IDBObjectStore”上执行“添加”

时间:2019-06-27 15:47:33

标签: javascript indexeddb

我正在尝试将JavaScript对象(函数构造函数)添加到 IndexedDB ,但出现错误

  

无法在“ IDBObjectStore”上执行“添加”:function(){               this.mapHierachyString = this.mapHierachyString.replace(/> / g,“ |”); // CHUSJ | Bloc 5 | B ......}无法克隆。

以下代码有什么问题吗?

      $.ajax({
          url: '/Review/GetDynamicPositions',
          type: 'POST',
          data: {
              ProfileId: profileId,
              DateDebut: dateDebut,
              DateFin: dateFin
          },
          
          success: function (reponse) {

              if (reponse.indexOf("Erreur") < 0) 
              {
                  review = new Review(profileId);
                  const dynamicPositions = JSON.parse(reponse);
                  dynamicPositions.forEach(dynamic => {
                      const dynamicPosition = new DynamicPosition();
                      dynamicPosition.positionX = dynamic.PositionX;
                      dynamicPosition.positionY = dynamic.PositionY;
                      dynamicPosition.floorId = dynamic.FloorId;
                      dynamicPosition.zoneId = dynamic.ZoneId;
                      dynamicPosition.mapHierachyString = dynamic.MapHierchString;

                      dynamicPosition.changeMapString();
                      review.addDynamicPosition(dynamicPosition);
                  });

                  //..Sauvegarder le review dans la BD
                  sauvegarderReview(review);
              }

          }

      });



function sauvegarderReview(review) 
{
        const transcation = db.transaction('ReviewStore', 'readwrite');
        const store = transcation.objectStore('ReviewStore');

        //..Ajouter dans la BD
        const request = store.add(review);

        request.onsuccess = function (e) 
        {
            console.log('Sauvegarder avec success');
        };

        request.onerror = function (e) {
            console.log("Error", e.target.error.name);

        };
}

//Review object 
function Review(profileId)
{
        this.profileId = profileId;
        this.dynamicPositions = [];

        this.addDynamicPosition = function (dynamicPosition) 
        {
            this.dynamicPositions.push(dynamicPosition);
        }

}

//DynamicPosition object 
function DynamicPosition() 
{
      this.positionX = 0;
      this.positionY = 0;
      this.mapHierachyString = ''; //CHUSJ>Bloc 5>B
      this.floorId = 0;
      this.zoneId = '';

      this.changeMapString = function () {
          this.mapHierachyString = this.mapHierachyString.replace(/>/g, "|"); 
          this.mapHierachyString = this.mapHierachyString.replace(/ /g, "_");
      }


}

2 个答案:

答案 0 :(得分:1)

The spec says:

  

每个记录都与一个值相关联。用户代理必须支持任何serializable object。这包括简单的类型,例如String原始值和Date对象以及Object和Array实例,File对象,Blob对象,ImageData对象等等。

基本上,这意味着您存储到IndexedDB的对象只能包含所有可能变量的有限子集。函数是不能存储在IndexedDB中的事物之一。根据您发布的错误消息,review对象中必须有一个函数。

如果要将review中的数据存储在IndexedDB中,则必须以某种方式进行转换,以使其不包含函数或任何其他有问题的数据类型。

答案 1 :(得分:0)

您必须首先对数据中的js函数(仅)进行序列化,然后将它们作为serializedData添加到indexedDb:

function serialize(value) {
    if (typeof value === 'function') {
        return value.toString();
    }
    if (typeof value === 'undefined' || value === null) {
        return value;
    }
    if (typeof value === 'object') {
        var serializeObject = {};
        for (const [objectKey, objectValue] of Object.entries(value)) {

          console.log(`objectKey=${objectKey}  value=${objectValue}`);
          serializeObject[objectKey] = serialize(objectValue);
        }
        return serializeObject;
    }

    return value;
}

然后反序列化:

function deserialize(valueNew) {
    if (valueNew.toLowerCase().startsWith( 'function(' ) ) {
        return Function('"use strict";return ' + valueNew);
    }
    if (typeof valueNew === 'undefined' || valueNew === null) {
        return valueNew;
    }
    if (typeof valueNew === 'object' ) {
        var deserializeObject = {};
        for (const [objectKey, objectValue] of Object.entries(valueNew)) {

          console.log(`objectKey=${objectKey}  value=${objectValue}`);
          deserializeObject[objectKey] = deserialize(objectValue);
        }
        return deserializeObject;
    }

    return value;
}

在您的inedexedDb代码中,将是这样的:

function addItem(name, item) {


  var itemObject = { name: name };

itemObject.item = serialize(item);

  var transaction = db.transaction(['store'], 'readwrite');
  var store = transaction.objectStore('store');
  var request = store.add(itemObject);

  request.onerror = function(e) {
    console.log('Error', e.target.error.name);
  };

  request.onsuccess = function(e) {
    console.log('Woot! added it');
  };

    transaction.oncomplete = function(e) {
        console.log('Woot! trans oncomplete');
    };

}

在获取密钥的keyData之后:

deserialize(keyData);