サービスから戻ってくる一連のアイテムがあります。Item インスタンスごとに計算されたオブザーバブルを定義しようとしているので、本能的にそれをプロトタイプに配置するように指示されます。
計算されたオブザーバブルの 1 つのケース: システムはポイントを計算しますが、ユーザーは計算された値をオーバーライドすることを選択できます。ユーザーがオーバーライドを削除した場合に備えて、計算された値を利用できるようにしておく必要があります。また、ユーザーが割り当てたポイントと計算されたポイントを合体させ、合計を合計する必要があります。
マッピングを使用して次のことを行います。
var itemsViewModel;
var items = [
{ 'PointsCalculated' : 5.1 },
{ 'PointsCalculated' : 2.37, 'PointsFromUser' : 3 }
];
var mapping = {
'Items' : {
create : function(options) {
return new Item(options.data);
}
}
};
var Item = function(data) {
var item = this;
ko.mapping.fromJS(data, mapping, item);
};
Item.prototype.Points = function () {
var item = this;
return ko.computed(function () {
// PointsFromUser may be 0, so only ignore it if the value is undefined/null
return (item.PointsFromUser != null) ? item.PointsFromUser : item.PointsCalculated;
});
};
ko.mapping.fromJS(items, mapping, itemsViewModel);
現在の動作方法では、無名関数を呼び出して、計算されたオブザーバブルを返す必要があります。これは、バインディングごとに計算されたオブザーバブルの新しいインスタンスを作成するように見えます。これは、プロトタイプに配置するという点のほとんどを無効にします。また、オブザーバブルにアクセスするたびに使用する括弧の数を解読しなければならないのは少し面倒です。
また、やや壊れやすいです。コードで Points() にアクセスしようとすると、できません
var points = 0;
var p = item.Points;
if (p && typeof p === 'function') {
points += p();
}
item ではなく、Points() のコンテキストが DOMWindow に変更されるためです。
マッピングに create() で計算されたものを配置すると、コンテキストをキャプチャできますが、各オブジェクト インスタンスにメソッドのコピーが存在します。
Michael Best の Google グループへの投稿 ( http://groups.google.com/group/knockoutjs/browse_thread/thread/8de9013fb7635b13 ) を見つけました。プロトタイプは、「アクティブ化」時に新しい計算されたオブザーバブルを返します。「アクティブ化」(おそらく Objs ?) と呼ばれるものはわかりませんが、オブジェクトごとに 1 回発生すると推測しており、「これ」がどのスコープを取得するかはわかりません。
この時点で、私は公開されたドキュメントで利用できるものを過ぎていると思いますが、ソースから何が起こっているのかを解読するためにまだ取り組んでいます.