では、ページにいくつかのアクティビティを表示することを想像して、簡単な例を見てみましょう。
- 返されたデータがすべて特定のプロパティを持つアクティビティの列挙であるとします。その場合、アクティビティは次のようになります。
var ActivityType = function (data) {
var self = this;
self.Id = ko.observable(data.Id);
self.Name = ko.observable(data.Name);
self.Description = ko.observable(data.Description);
self.Selected = ko.observable(data.Selected); };
次に、このアクティビティモデルにマップする必要があるアクティビティというプロパティを持つビューモデルがあるため、アクティビティの列挙を取得すると、その配列に同じ数の新しいアクティビティタイプが自動的に生成されます。
var activitiesViewModel = {};
そのためのマッピング ユーティリティを定義します (単純に、新しい ActivityTypes は異なる Id を持つものであるため、新しいものを作成します)。
var ActivityTypeDataMappingOptions = {
key: function (data) {
return data.Id;
}, create: function (options) {
return new ActivityType(options.data, null);
}
}
そのため、ビュー モデルに activities プロパティが必要です。
activitiesViewModel.Activities = mapping.fromJS([]);
これは、マッピング データに基づいて監視可能な配列を作成することを意味します。
そのコールバックでデータを提供する datacontext が定義されているとします。
datacontext.getActivities(function (data) {
mapping.fromJS(data.Activities, ActivityTypeDataMappingOptions, activitiesViewModel.Activities);
ko.applyBindings(activitiesViewModel);
});
mapping.fromJS は 3 つのパラメーターを取ります。1 つ目はデータを保持するコレクション、2 つ目は定義したマッピング ユーティリティです。そのため、監視可能なコレクションを保持するビュー モデルのプロパティから新しいアクティビティを作成し、最後に保持します。
したがって、これを次のように使用できます。
<ul data-bind="foreach: Activities">
<li><input type='text' data-bind="value: Name" /></li>
</ul>
<button data-bind="click: updateActivities">Update Activities</button>
- 注: この例では、ビュー モデルはシングルトンですが、使用方法に応じて、公開プロトタイプ パターンを使用してインスタンス化可能なオブジェクトにしたい場合があります。次に、ko.applyBindings を呼び出すときに、新しい activitiesViewModel() をパラメーターとして渡す必要があります。
結果を更新して送り返すために、updateActivities を定義する必要があります。
activitiesViewModel.updateActivities = function(){
// Let's say our data context also has a setActivities method that requires a payload of activities object for Post
datacontext.setActivities({
// as activitiesViewModel.Activities is an observable array then this will always have the latest values which might have changed in your UI
activities : ko.toJSON(activitiesViewModel.Activities)
}, function(data){
// Lets say the POST will return true if the call was successful
if (data) alert("all done");
});
};
この関数をバインドして入力を変更することもできますが、API 呼び出しが多すぎるため、お勧めしません。
これらのモデルを大量に作成し、それをビュー モデルで使用する場合、サーバー側で既に行われている多くのモデリングを行っていることにすぐに気付くでしょう。私の例のActivityTypeなど、モデルを含むjsファイルを自動的に生成するサーバー側コードを作成する場合、requireJSを使用してそれらをビューモデルファイルにインポートし、アプリケーション全体で使用できます。これにより、バックエンドでモデルを更新するだけで、プロパティ名の変更と更新をフロントエンドで自動的に利用できるようになります。