2011-08-08 9 views
2

メインのUIとしてコンテキストメニューを使用するGoogle Chrome拡張機能を作成しています。各メニュー項目は同じ内容のスクリプトをトリガーしますが、パラメータは異なります。コンテキストメニューがあるときに階層を作成するために使用されているJavaScript配列が正しく埋められない

{name, parent_id, rule_number, meta_array[], childCount} 

名、child_countとPARENT_ID:私は基本的にやったことは次の形式を持つJSONオブジェクトの形式ですべての項目(およびそれに対応するデータ)を格納しています建てられた。スクリプトに渡されるデータは、rule_number(int)およびmeta_array(文字列の配列)です。これらのオブジェクトはすべて、indexData []という配列に格納されます。

メニュー項目をクリックすると、提供されたIDは "indexData"配列のインデックスとして使用され、適切なデータを取得してスクリプトに渡します。例えば

// Iterates through the objects 
for(var j = 0; j < objectsArray.length; j++) { 

// Context menu created with unique id 
var id = chrome.contextMenus.create({ 
"title": objectArray[j].name, 
"onclick": injectScript, 
"parentId": objectsArray[j].parent_id }); 

// Stores the objects at the corresponding index 
indexData[id] = objectsArray[j]; } 

、しばしば戻ってくるデータの特定の大規模なセットがありました。私がこれらの要素をメニューの一部として必要とするたびに、これらの要素を1つずつリストするのではなく、このデータセットを子として必要とするすべてのJSONオブジェクトに真偽値パラメータを追加するだけです。メニューが作成されると、このブール値がtrueに設定されている場合に関数が呼び出されます。スクリプトはオブジェクトの別のリストを反復して、この親オブジェクトの子にします。作成された子も親オブジェクトから特定のものを継承します。

たとえば、親オブジェクトに["1"、 "2"、 "3"、 "4"]のようなmeta_arrayがある場合、その子はすべて["1"、 "2" custom_children_data [3]、 "4"]。

問題はこの最後の部分が機能しないことです。子供たちは正しい名前でうまく作成されますが、それに関連するデータは間違っています。常に別のリストの最後のオブジェクトのデータになります。この関数は次のようになります。ループの最初の繰り返しで

// Iterate through children list 
for(var i = 0; i < separateList.length; i++){ 

// Just copying the passed parent object's data 
var parentData = data; 

var id = chrome.contextMenus.create({ 
"title": separateList[i].name, // Get item [i] of the children list (works fine) 
"onclick": injectScript, 
"parentId": parentId   // Will become a child of parent object 
}); 


// Trying to change some data, this is where things go wrong. 
parentData.meta[2] = separateList[i].meta; 

// Save in indexData 
indexData[id] = parentData; } 

、parentData.metaは、[2]のリストから正しい値を取得し、この値は、その後INDEXDATAに保存されます。しかしその後の反復では、すでにindexDataに存在するすべての値がスワイプされ、リストから読み取られる最新のデータに置き換えられます。最後の値が読み込まれると、indexDataの新しく追加されたすべての要素がその最後の値に変更され、私の問題が説明されます。しかし、なぜそれはそれを行うだろうか? Javaは何らかの理由で値の代わりにアドレスで配列を扱うのでしょうか?

多分私は本当に明白な何かを見逃しているかもしれませんが、多くの試みの後に私はまだこれを正しく動作させることができません。できるだけ具体的なものにしようとしましたが、何か言及するのを忘れてしまったので、他のことを知りたい場合はすぐに尋ねてください。

ありがとうございました。

答えて

3

この問題は、indexData [id]をparentDataへの参照にしてから、ループの次の繰り返しでparentDataを変更しているindexData[id] = parentDataになります。

親データが単純配列(少なくとも1つの配列またはオブジェクトを含む)ではないため、slice(0)を使用してコピーを作成することはできません。あなた自身のコピー機能を書かなければならないか、またはそれを持っているライブラリを使う必要があります。

+0

問題は実際に 'parentData.meta [2] = separateList [i] .meta'に現れた場合、' indexData [id] = parentData'イベントにありますか? –

+0

'separateList [i] .meta'は配列かオブジェクトか、単純な型ですか?もしそれが常に単純な型であれば、その行に問題はありません。もしそれがオブジェクトでも配列でもかまいませんし、**後であなたのコードで 'separateList [i] .meta'を修正すれば、同じ問題があります両方の行に表示されます。 – Paulpro

+0

よろしく!それは働くようになった。私は 'indexData [id]'に割り当てられたダミーオブジェクトを作成してから、それを修正しました。 'indexData [id] = {name:" FOO "、parent_id:2、rule:" 11 "、meta :[null、null、null、null]、childCount:0} ' ' indexData [id] .meta [2] = separateList [i] .meta; ' ありがとうございました! –

3

私の推測では、あなたの問題がどこにあるか、これがあることである:これは、実際には、データをコピーしません

// Just copying the passed parent object's data 
var parentData = data; 

。むしろdataへの参照を作成するので、parentDataに加えられた変更はdataにも同様に変更されます。 dataオブジェクトを "複製"したい場合は、手動で行うか、そうするための関数を持つライブラリを見つける必要があります。

+0

//変更点http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone function CloneObject(obj){ if(obj === null || typeof(obj)!) = 'オブジェクト'){return obj; } var temp = {}; (key){ temp [key] = obj [key]; の場合、{ if } } return temp; } – JoshNaro

関連する問題