Knockoutをもう少し長く使用した後、マッピングプラグインに、マッピングプロセスをよりきめ細かく制御できるいくつかの追加オプションがあることに気付きました。
生成されるプロパティのタイプと量を制御する
これを実現する方法はいくつかあります。いくつか説明しますが、すべてが観察可能ではないため、最終的にはマッピングプラグインの結果がより明るくなります。
基本的に、変更されるとは思わないものはすべて通常のプロパティとして残し、観察したい特定のアイテムからのみ観察可能なものを作成します。
特定のプロパティをmapping
省略します
ignore
またはのようなものを指定することにより、マッピングプラグインに最終結果からプロパティを完全に省略させることができますinclude
。これらは両方とも、まったく逆の方法で同じことを達成します。
注:サンプルは、knockout.jsマッピングプラグインのドキュメントからのものです。コメントは私が追加しました
マッピングプラグイン引数:include
次のスニペットは、引数 を介して渡されたプロパティ以外のすべてのプロパティをソースオブジェクトから省略します。include
// specify the specific properties to include as observables in the end result
var mapping = {
// only include these two properties
'include': ["propertyToInclude", "alsoIncludeThis"]
}
// viewModel will now only contain the two properties listed above,
// and they will be observable
var viewModel = ko.mapping.fromJS(data, mapping);
マッピングプラグイン引数:ignore
ソースオブジェクトから特定のプロパティのみを省略したい場合は、ignore
以下に示すように引数を使用します。指定されたプロパティを除く、ソースオブジェクトのすべてのプロパティからオブザーバブルを作成します。
// specify the specific properties to omit from the result,
// all others will be made observable
var mapping = {
// only ignore these two properties
'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
// viewModel will now omit the two properties listed above,
// everything else will be included and they will be an observable
var viewModel = ko.mapping.fromJS(data, mapping);
監視可能にするプロパティとしないプロパティを制御します
プロパティを含める必要があるが、(何らかの理由で)それらを監視可能にする必要がないと思われる場合は、マッピングプラグインに役立つ機能があります。
マッピングプラグイン引数:copy
マッピングプラグインでプレーンプロパティを単純にコピーし、それらを監視可能にしないようにする場合は、以下に示すように、この引数を使用します。
// tell the mapping plugin to handle all other properties normally,
// but to simply copy this property instead of making it observable
var mapping = {
'copy': ["propertyToCopy"]
}
var viewModel = ko.mapping.fromJS(data, mapping);
マッピングプロセスを完全に制御できます
オブジェクトにクロージャやサブスクリプションを配置する機能など、マッピングプロセスで作成されるものを100%制御したい場合は、「作成」オプションを使用します。
計算されたプロパティを含む単純な結果
これは、ajax呼び出しからのデータをresults
プロパティを持つオブジェクトにマッピングしていた例です。観察可能なものは必要ありませんでした。オブジェクトの他の単純なプロパティで構成される、単純に生成されたプロパティが必要でした。おそらく最も説得力のある例ではありませんが、機能を示しています。
var searchMappingConfig = {
// specific configuration for mapping the results property
"results": {
// specific function to use to create the items in the results array
"create": function (options) {
// return a new function so we can have the proper scope/value for "this", below
return new function () {
// instead of mapping like we normally would: ko.mapping.fromJS(options.data, {}, this);
// map via extend, this will just copy the properties from the returned json element to "this"
// we'll do this for a more light weight vm since every last property will just be a plain old property instead of observable
$.extend(this, options.data);
// all this to add a vehicle title to each item
this.vehicleTitle = this.Year + "<br />" + this.Make + " " + this.Model;
}, this);
};
}
}
}
サブスクリプションとクロージャとマッピング
もう1つの状況は、結果にクロージャとサブスクリプションが必要な場合です。この例は長すぎて全体を含めることはできませんが、車両のメーカー/モデル階層の場合です。モデルが有効になっていない場合は、特定のメーカー(親)のすべてのモデル(子)を無効にし、サブスクリプションを使用してこれを実行する必要がありました。
// here we are specifying the way that items in the make array are created,
// since makes has a child array (Models), we will specify the way that
// items are created for that as well
var makesModelsMappingConfig = {
// function that has the configuration for creating makes
"create": function (options) {
// return a new function so we can have the proper
// scope/value for "this", below
return new function () {
// Note: we have a parent / child relationship here, makes have models. In the
// UI we are selecting makes and then using that to allow the user to select
// models. Because of this, there is going to be some special logic in here
// so that all the child models under a given make, will automatically
// unselect if the user unselects the parent make.
// make the selected property a private variable so it can be closure'd over
var makeIsSelected = ko.protectedComputed(false);
// expose our property so we can bind in the UI
this.isSelected = makeIsSelected;
// ... misc other properties and events ...
// now that we've described/configured how to create the makes,
// describe/configure how to create the models under the makes
ko.mapping.fromJS(options.data, {
// specific configuration for the "Models" property
"Models": {
// function that has the configuration for creating items
// under the Models property
"create": function (model) {
// we'll create the isSelected as a local variable so
// that we can flip it in the subscription below,
// otherwise we wouldnt have access to flip it
var isSelected = ko.protectedComputed(false);
// subscribe to the parents "IsSelected" property so
// the models can select/unselect themselves
parentIsSelected.current.subscribe(function (value) {
// set the protected computed to the same
// value as its parent, note that this
// is just protected, not the actual value
isSelected(value);
});
// this object literal is what makes up each item
// in the Models observable array
return {
// here we're returning our local variable so
// we can easily modify it in our subscription
"isSelected": isSelected,
// ... misc properties to expose
// under the item in the Model array ...
};
}
}
}, this);
};
}
};
全体として、私が見つけたのは、プラグインに渡すオブジェクトの100%が必要になることはめったになく、監視可能にするためにオブジェクトの100%が必要になることはめったにないということです。マッピング構成オプションを掘り下げて、あらゆる種類の複雑で単純なオブジェクトを作成します。アイデアは、必要なものすべてを取得することであり、多かれ少なかれ何も取得しません。