2016-05-26 24 views
0

TypeScriptでは、Web Storage APIの周りにラッパークラスがあります。ストレージを使いやすくするために、アプリケーションが保存する必要があるすべてのアイテムのクラスプロパティを初期化しました。以下は、(活字体で書かれた)私のラッパークラスWeb Storage:オブジェクトメンバを編集する方法

エクスポートクラス

get Storage(){return localStorage} 
get testData(){return this.getItem('testData')} 
set testData(val){this.setItem('testData',val)} 

getItem(key:string){return JSON.parse(this.Storage.getItem(key))} 
setItem(key:string, data:any){this.Storage.setItem(key, JSON.stringify(data))} 
removeItem(key){this.Storage.removeItem(key)} 
clear(){this.Storage.clear()} 

アプリケーションの他の場所でStorageServiceがあり、私はオブジェクトtestDataとそのメンバーのプロパティと対話したいと思います。以下では正常に動作します:私はTESTDATAのプロパティを変更するのではなく、全体のオブジェクトを設定しようとした場合

storage.testData = {name:'Mary',age:6}; 
console.log(storage.testData); //initial object is retrieved 

しかし、setItemメソッドが呼び出されることはありませんし、ストレージの内容は変更されません。

storage.testData.age = 10; 
console.log(storage.testData); //{name:'Mary',age:6} <- age was not changed 

直感的な修正が最初にそれを更新し、保存されたオブジェクトを取得し、最終的にこれは小さなオブジェクト上の罰金​​ですが、それがうまくスケールしない更新された値

var temp = storage.testData; 
temp.age = 10; 
storage.testData = temp; 
console.log(storage.testData); //{name:'Mary',age:10} <- age is updated 

を格納することです。 testDataに50または60のプロパティがあり、アプリの複数のポイントで1つまたは2つだけ変更する必要があるとします。毎回すべての物件を設定する必要はありません。とにかく、私はアプリケーションの残りの部分を変更することができないかもしれません。私はストレージインターフェイスだけを提供します。

私の質問は、毎回保存するオブジェクト全体を提供するのではなく、ストレージ内のオブジェクトのプロパティを直接設定/変更できるストレージメソッドを公開するにはどうすればいいですか?理想的には、消費コードは現在格納されている値を編集するのにstore.testData.age = valueを呼び出すだけです。

PS:これは別のトピックの場合もありますが、localStorageにアクセスすると、多くの場合、アプリケーションの速度が遅くなります(最初のコメントのとおり)。おそらく、私のラッパーは値をメモリに格納することができますが、設定された間隔でそれらをすべてストレージにプッシュします。 3分ごとに?私は厳密にメモリオブジェクトにアプリケーションの状態を反映していましたが、ユーザーがページを移動したりページを更新したりすると、すべてが失われます。

+0

多くの変更を加えたい場合は、変更するたびに文字列化してオブジェクト全体を格納するのが適切です。あなたの現在の方法(最後に保存する)は適切です。ちなみに、 'Storage'オブジェクトにはすでにゲッターとセッターがあります。 – Oriol

+0

詳細をご覧ください。上記の両方の方法は、すべての変更時に文字列化する必要はありませんか?これは別の話題かもしれませんが、localStorageにアクセスするとたくさんのアプリが本当に減速しますが、意図したとおりにストレージを使用していない可能性があります。おそらく、私のラッパーは値をメモリに格納することができますが、設定された間隔でそれらをすべてストレージにプッシュします。 3分ごとに?私は厳密にメモリオブジェクトにアプリケーションの状態を反映していましたが、ユーザーがページを移動したり、ページを更新したりすると、すべてが失われます。 – BeetleJuice

+0

を 'var temp = storage.testData'に置き換えてストレージにアクセスし、JSONを解析します。そうすれば、オブジェクトに膨大な量の変更を加えることができます。これはストレージに保存されません(高速です)。最後に、文字列化して 'storage.testData = temp'で保存します。 – Oriol

答えて

0

私がOPで述べたように、 。呼び出しコードは、理想的には、ストレージ内のオブジェクトのメンバプロパティに変更を加えることができます。私はハイブリッドなアプローチを試みると思う。アイテムをメモリに保存しますが、設定された間隔ごと(または特定のコマンドに応じて)、アイテムをストレージに保存します。以下は私の単純化されたStorageServiceは活字体

//push items to storage regularly 
constructor() {this.restore();this.intervalID = setInterval(()=>this.commit(),this.COMMIT_INTERVAL*1000)} 

Storage = window.localStorage; 
COMMIT_INTERVAL = 60;//interval, in seconds, upon which changes are saved to storage 
private intervalID:number; 
private keys = ['testData', 'testData2']; //key names used set items in storage 

//when data is accessed, return it from memory. If not there (eg after a page refresh), then from storage 
private _testData = null; 
public get testData(){return this._testData || this.getItem(this.keys[0])} 
public set testData(val){this._testData = val} //we store in memory; not directly in storage until commit() is called. 

//remove each value from memore and clear web storage 
public clear(){ 
    this.keys.forEach(key=>this['_'+key]=null,this); 
    this.Storage.clear() 
} 

// store memory data in web storage 
public commit(){  
    this.keys.forEach(key => this.setItem(key,this['_'+key]),this); 
} 

//restore items from web storage. This is done in the constructor 
private restore(){ 
    this.keys.forEach(key => this[key] = this.getItem(key) || this[key]) 
} 

//the methods that actually connect to storage are all private. Calling code must use commit() to interact with storage 
private getItem(key:string){ 
    return JSON.parse(this.Storage.getItem(key)); 
} 
private removeItem(key){ 
    this.Storage.removeItem(key); 
} 
private setItem(key:string, data:any){ 
    this.Storage.setItem(key, JSON.stringify(data)); 
} 

あるこのサービスは、呼び出し元のコードは同じままに使用するAPIを許可します(commit()が呼び出されたとき)testData.age = 10は、ストレージ内のメモリにオブジェクトを更新し、最終的になります。

フィードバックをお願いします。私は費用のかかる間違いをコーディングして疲れてしまいました。

関連する問題