2011-01-12 3 views
2

私の見解では、マップ関数に渡されるオブジェクトの代わりに返す新しいオブジェクトを作成します。いくつかの検証を行い、新しいオブジェクトにいくつかのフィールドを追加したいと思います。ビューのためのマイマップ機能は、この(軽減がない)ようになっていますCouchDB:ビュー内の "doc"へのフィールドの追加

function(doc) { 
    if(doc.type == "mytype") { 
     var newobj = null; 
     if(doc.someObjField) { 
      newobj = doc.someObjField; //LINE 5: want a copy but get a reference 
     } 
     else { 
      newobj = new Object();  //field didn't exist create a new object 
     } 

     newobj.superId = doc._id;  //these fields get added to the DB 
     newobj.superName = doc.name; 
     newobj.newField = doc.field; 

     emit(doc._id, newobj); 
    } 
} 

問題は、このビューを実行すると、それはデータベース内の文書にいくつかの新しいフィールドを追加して終わるということです。 Futonのドキュメントを編集するときにフィールドが表示されませんが、ドキュメントのすべてのビューに表示されます。

これは、LINE 5がコピーの代わりにドキュメントのそのフィールドへの参照を作成するためです。これは、私が望むものを得るために私のすべてのビューにclone()関数を含める必要があるということですか?多分私はこの間違いを考えているのだろうか?

アップデート:私はCouchDBのバージョン1.0.0を使用して、バージョン1.0.1にアップグレードし、動作が変更されたことを思われました。以前のバージョンでは、 "doc"が1つのビューで変更されたとき、その変更はすべてのビューで表示されました。最新のバージョンでは、これはそうではないようです。

+0

あなたの説明は少し不明です。ビューを使用してDBを変更しようとしていますか?ビューは読み取り専用のデータ変換です。 futonを使用してビュー行をクリックすると、その行を生成するために使用されたドキュメントが表示されます。ビューで "作成した"ドキュメントはDBに存在しません。それはあなたが発行したものです。 –

+0

DBに格納されているドキュメントではなく、ビューから返された結果を変更したい。私が問題を抱えていたのは、DB内のドキュメントが変更されて他のビューが混乱しているように見えることでした。 –

答えて

3

newobj = doc.someObjField実際には参照でありコピーではないので、doc.someObjFieldのプロパティを反復して新しいオブジェクトにコピーする必要があります。

これは、その簡単ではありませんが、以下が浅いクローンを作成する方法の例を示します。

// get the class of an object, this is a lot better than messing with typeof and instanceof 
function is(type, obj) { 
    return Object.prototype.toString.call(obj).slice(8, -1) === type; 
} 

function copy(val) { 
    if (is('Object', val)) { // shallow clone objects 
     var obj = {}; 
     for (var f in val) { 
      if (val.hasOwnProperty(f)) { 
       obj[f] = val[f]; 
      } 
     } 
     return obj; 

    } else { 
     return is('Array', val) ? val.slice() : val; // shallow clone arrays 
    } 
} 

あなたのコードは次のようになります。今

newobj = doc.someObjField ? copy(doc.someObjField) : {}; 

あなたsomeObjFieldオブジェクトを持っている場合または配列をそのプロパティとして使用すると、それらは再び参照のみになるので、それらを再帰的に複製する必要があります。

+0

ディープクローンは 'eval(uneval(objToBeCloned))'でも使えますか?私はCouchDBを初めて使っているので、残念ながらこれについて間違っています。 – Hristo

+0

'var clone = JSON.parse(JSON.stringify(doc))'はとてもうまく動作します。 – Themerius

関連する問題