エンティティのグラフに対して基本的な CRUD 操作を実行する Knockout.js アプリケーションを作成しています。サーバーから JSON でエンコードされた 2 つのオブジェクトを読み込みます。
function UploadedImage(data) {
this.UploadedImageId = data.UploadedImageId;
this.Url = data.Url;
this.Name = data.Name;
this.AltText = data.AltText;
}
...次のように、AJAX リクエストを介して ViewModel に格納されます。
$.post("@Url.Action("JsonRepairData")", {}, function (response) {
self.repairData(_.map(response.repairData, function(d) { return new AppleProduct(d); }));
self.images(_.map(response.images, function (i) { return new UploadedImage(i); }));
self.dataLoaded(true);
}, 'json');
オブジェクト グラフとイメージ配列の両方で、データがすべて正しく読み込まれていることを確認しました。オブジェクト グラフ内のイメージ ID は、配列内のイメージ ID に対応します。オブジェクト グラフで関連するデータ エントリに対して選択されている画像を表示するために、次のような選択リストを選択しました。
<tbody data-bind="foreach: repairData">
<tr>
<td>@Html.TextBoxFor(m => m.Name, new { data_bind = "value: Name" })</td>
<td><select data-bind="options: $root.images, optionsCaption: 'Pick an image...', optionsValue: 'UploadedImageId', optionsText: 'Name', value: UploadedImageId"></select></td>
<td data-bind="html: ImgTag"></td>
<td><a href="#" data-bind="click: $root.deleteProduct">delete</a></td>
</tr>
</tbody>
ViewModel に含まれる repairData は、前述のオブジェクト グラフであることに注意してください。他のすべてのデータは正しくバインドされます。選択ボックスが正常に表示されます。ViewModel にバインドされている UploadedImageId の値は、選択ボックスが操作されると更新されます。ただし、(オブジェクト グラフからの) UploadedImageId の ViewModel の初期値は無視され、ページがレンダリングされると、UploadImageId はすぐに undefined に更新されます。オブジェクト グラフで UploadedImageId の初期値を設定する方法は次のとおりです。
function AppleProduct(data) {
var productSelf = this;
this.Id = data.Id;
this.Name = ko.observable(data.Name);
this.UploadedImageId = ko.observable(data.UploadedImageId);
this.Variations = ko.observableArray(_.map(data.Variations, function (v) { return new ProductSeries(v); }));
this.ImgTag = ko.computed(function () {
var img = _.find(self.images(), function (i) { return i.UploadedImageId == productSelf.UploadedImageId(); });
return img ? '<img src="'+img.Url+'" />' : '';
});
// Remove computed ImgTag from data addressed to the server
this.toJSON = function () {
var copy = ko.toJS(this);
delete copy.ImgTag;
return copy;
};
}
セレクトボックスを何時間も正しく設定する方法を見つけようとしてきましたが、まだ完全に困惑しています。私が判断できるのは、2.1.0 のノックアウト js ソース ファイルでは、1402 行目の選択ボックスの初期値を設定するコード (以下を参照) が 2 回渡されていることだけです。最初はモデル値がイメージ ID に適切に対応しますが、element.options.length == 0 であるため、モデル値は使用されません。このコードが 2 回目に渡されると、モデルの値はすべて未定義ですが、選択ボックスにはデータが入力されているため (つまり、element.options.length は正の数です)、適切な初期値が設定されていません。
for (var i = element.options.length - 1; i >= 0; i--) {
if (ko.selectExtensions.readValue(element.options[i]) == value) {
element.selectedIndex = i;
break;
}
}
私が欠けているものを理解するための助けがあれば大歓迎です!