2

まだ存在しない限り、ある配列から別の配列にアイテムを移動し、それをに格納していますlocalStorage

var queue = [];

function moveToQueue(item) {
    if(queue.indexOf(item) == -1) {
        queue.push(item);
        store();
    }
}

function store() {
    localStorage.myApp_queue = JSON.stringify(queue);
}

ページが読み込まれると、load 関数を呼び出します。

function load() {
    if(typeof localStorage.myApp_queue != 'undefined') {
        queue = JSON.parse(localStorage.myApp_queue);
    }
}

この時点で、私のインターフェイスqueueには最後に残したままの が表示されますが、同じアイテムを再度追加しようとすると、「queue.indexOf(item)」が失敗します。の内容は、メソッドが呼び出されるqueue前と同じではありません。store()/load()

console.log()ページのリロード前後のいくつかの呼び出しは、空のqueue. moveToQueue関数の先頭にログが追加されました

function moveToQueue(item) {
    console.log('adding to queue');
    console.log(item);
    console.log(queue[0]);
    console.log(queue.indexOf(item));
    ...

初期負荷:

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
undefined
-1

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
0 

ページの更新後 - プッシュしているアイテムはすでにqueue配列内にあります

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "006", $get: function…}
Object {id: 1, status: "A", title: "Comcar", $$hashKey: "004"}
-1

ここで見逃したもの、配列を変更するために何をlocalStorageしているのか。JSON

ログには、ストレージから返されたアイテムが「オブジェクト」としてリストされていることがわかりますが、元のアイテムの「タイプ」(それについてはよくわかりません) は「e」です。

両方の結果を使用するtypeofと、「オブジェクト」になります

4

2 に答える 2

3

indexOfオブジェクトの場合、参照によって値を比較するため、コードは複雑なオブジェクト (つまり、ハッシュ、辞書など) では機能しません。オブジェクトが等しいかどうかをチェックする関数を使用すると、オブジェクトに対してもコードを機能させることができます。そのような関数はここにあります: JavaScript でのオブジェクト比較

次のセクションでは、次のことができるサンプル コードを示します。

  1. を使用して配列/オブジェクトをロードおよび保存しますlocalStorage
  2. プリミティブに対してコードが機能するようにします。
  3. 複雑なオブジェクトに対してコードが機能するようにします。

localStorage への読み込みと保存

//Saving array with specific "name" (key for the localStorage)
function saveArray(name, array) {
   localStorage.setItem(name, JSON.stringify(array));
}

//Loads specific array and deserialize it.
function loadArray(name) {
   return JSON.parse(localStorage.getItem(name));
}

プリミティブの場合:

プリミティブの場合、必要な機能を非常に簡単に実現できます (コードはこの種のデータに適しています)。

//This method adds unique elements, which are not already in the array
Array.prototype.addUnique = function (item) {
   if (this.indexOf(item) < 0) {
      this.push(item);
   }
};

var array = [];
array.addUnique(1);
array.addUnique(2);
array.addUnique(1);
array.addUnique(3);
//The current content of the array is [1,2,3] because of the addUnique functionality
saveArray('myarray', array);

ページをリロードするときは、次を使用します。

var array = loadArray('myarray'); //[1,2,3]
array.addUnique(6);
saveArray('myarray', array);

localStorageの値はarrayになります[1,2,3,6]

オブジェクトの場合

キーと値のペア オブジェクトのように、配列にさらに複雑なデータがある場合は、次を使用します。

//Code from here:
//https://stackoverflow.com/questions/1068834/object-comparison-in-javascript
Object.prototype.equals = function(x) {
  var p;
  for(p in this) {
      if(typeof(x[p])=='undefined') {return false;}
  }

  for(p in this) {
      if (this[p]) {
          switch(typeof(this[p])) {
              case 'object':
                  if (!this[p].equals(x[p])) { return false; } break;
              case 'function':
                  if (typeof(x[p])=='undefined' ||
                      (p != 'equals' && this[p].toString() != x[p].toString()))
                      return false;
                  break;
              default:
                  if (this[p] != x[p]) { return false; }
          }
      } else {
          if (x[p])
              return false;
      }
  }

  for(p in x) {
      if(typeof(this[p])=='undefined') {return false;}
  }

  return true;
}

Array.prototype.exists = function (item) {
   var exists = false;
   this.forEach(function (e) {
      if (e.equals(item)) {
         exists = true;
         return;
      }
   });
   return exists;
};

Array.prototype.addUniqueObject = function (item) {
    if (!this.exists(item)) {
       this.push(item);
    }
};

var array = [];
array.addUniqueObject({ foo: 'bar' });
array.addUniqueObject({ foo: 'baz' });
array.addUniqueObject({ foo: 'bar' });
array.addUniqueObject({ foo: 'foobar' });
//The current content of the array is [{ foo: 'bar' }, { foo: 'baz' }, { foo: 'foobar' }] because of the addUniqueObject functionality
saveArray('myarray', array);

ページをリロードすると、次を使用して同じコンテンツの配列を取得できます。

loadArray('myarray');
//[{ foo: 'bar' }, { foo: 'baz' }, { foo: 'foobar' }]

ノート

メソッドequalsが追加されるObject.prototypeように、作成するすべてのオブジェクトにこのメソッドが追加されます! addUniqueaddUniqueObjectおよびを持つ各配列についても同じですequals

これが望ましくない場合は、これらのメソッドを少しリファクタリングするだけです。

于 2013-02-19T12:37:59.673 に答える
2

ここで見逃したものは何ですか? localStorage と JSON は配列を変更するために何をしているのでしょうか?

配列は変更されません (ページのアンロード時に古い配列が失われました)。まったく新しい項目オブジェクトを使用して、まったく新しいものを作成します。すでに持っているアイテムとまったく同じように見えるアイテムを作成した場合でも、それらは 2 つの別個のオブジェクトであり、参照によって比較すると (そうindexOfであるように===) 生成されfalseます。

そのため、構築関数を変更して、新しいものを構築せずに古いものを再利用するか、たとえば ID によってオブジェクトの等価性を伝える特別な比較関数を使用する必要があります。

于 2013-02-19T12:58:48.433 に答える