2012-03-09 6 views
6

私はずっとこれを今のところ把握しようとしています。この問題に対処するものは何も見つかりませんでしたが、間違っていれば私を修正してください。KnockoutJS:マッピングを使用してviewModelにデータを更新/挿入します。

問題: 入れ子の配列/オブジェクト構造を持つJSON APIのデータがあります。私はマッピングを使って最初にモデルに自分のデータを埋めます。これを更新するには、新しいデータが到着した場合にモデルを拡張するか、既存のデータを更新する必要があります。

私が知っている限り、マッピングオプションキーは、私にとってこのトリックを行うべきですが、私はマッピングオプションの機能を誤解しているかもしれません。私はこの例で表現される問題を煮詰めてきた

var userMapping = { 
    key: function(item) { 
     return ko.utils.unwrapObservable(item.id); 
    } 
}; 

// JSON call replaced with values 
var viewModel = { 
    users: ko.mapping.fromJS([], userMapping) 
}; 

// Should insert new - new ID? 
ko.mapping.fromJS([{"id":1,"name":"Foo"}, {"id":2,"name":"Bar"}], userMapping, viewModel.users); 

// Should only update ID#1 - same ID? 
ko.mapping.fromJS([{"id":1,"name":"Bat"}], userMapping, viewModel.users); 

// Should insert new - New ID? 
ko.mapping.fromJS([{"id":3,"name":"New"}, {"id":4,"name":"New"}], userMapping, viewModel.users); 

ko.applyBindings(viewModel);​ 

はフィドル:あなたが見ることができるようにhttp://jsfiddle.net/mikaelbr/gDjA7/

、最初の行は、データを挿入します。すべての良い。しかし、更新しようとすると、コンテンツが置き換えられます。 3番目のマッピングでも同じです。コンテンツを拡張するのではなく、コンテンツを置き換えます。

間違っていますか?マッピングを使用する前にコンテンツを「手動で」拡張する必要がありますか?

編集ソリューション:
私は、現在のすべてのモデルを格納する第2のヘルパー配列を持つことによって、このケースを解決しました。新しいデータでは、この配列を拡張し、蓄積されたアイテムを含むようにビューモデルを更新しました。

更新時(私の場合はWebSocketメッセージ)、モデルをループして問題のアイテムの内容を変更し、メソッドvalueHasMutated()を使用して変更された値をKnockoutのlibに通知しました。

答えて

4

あなたの例のコードでマッピング・プラグインを探してから、私はそれを期待どおりに動作しています。コレクション上でfromJSと呼ぶと、マッピングプラグインを効果的に伝えています。これは、そのコレクションの新しいコンテンツです。例:

2番目の行で、更新しているかどうか、または単にid:2を削除したかどうかを知ることができますか?

データを単純に更新として扱う適切な方法はありませんが、追加することはできません。マップされた配列には、特定の項目を見つけるのに役立つ便利なメソッド(mappedIndexOfなど)が付いています。更新データセットを受け取った場合は、そのデータセットをループして、そのアイテムを見つけ、その特定のアイテムへのmapping.fromJSコールで更新します。これは、再利用可能な方法に容易に一般化することができます。

+0

はい。これは多かれ少なかれ私がそれを解決したものです。 – mikaelb

+0

これに関するご意見:http://stackoverflow.com/questions/20397054/knockout-js-mapping-keys-and-kendo-ui-grid – jtromans

0

はい、すべてのデータをリストまたは配列に収集してから、そのリストにマッピングを適用する必要があります。それ以外の場合は、viewModelの値を上書きします。

1

ko.mapping.updateFromJS()を使用すると、既存の値を更新できます。ただし、新しい値が追加されることはありません。そのため、インスタンス内で問題が発生します。詳細は以下のリンクをご覧ください。

Using updateFromJS is replacing values when it should be adding them

+4

updateFromJS()メソッドは、2011年8月https://github.com/SteveSanderson/knockout.mapping/commit/bff3c1864a5fd45289933b35de1ef70af4aed6b5 – mikaelb

+0

1 @mikaelbで削除されました - 私はそれを実現しませんでした。情報をありがとう。 –

関連する問題