顧客注文と多くの注文項目をモデル化する KnockoutJS ビューモデルを作成しようとしています。初期データをロードし、データを検証したいと考えています。
これまでのところ、knockoutjs.mapping を使用してデータをロードし、マッピングを使用して追加されたデータを検証できます。
// data to load into viewmodel
var modeldata = {
"OrderID":1,
"ReturnString":null,
"CustomerName":"First Customer",
"OrderDate":"2013-09-16T19:41:40.1639709+01:00",
"OrderItems": [
{"ItemID":0,
"ItemName":"Name_0",
"ItemPrice":0.0,
"_destroy":false
},
{"ItemID":1,
"ItemName":"Name_1",
"ItemPrice":10.0,
"_destroy":false
},
{"ItemID":2,
"ItemName":"Name_2",
"ItemPrice":20.0,
"_destroy":false
}
]
};
// setup defaults for validation
var validationOptions = {
insertMessages: true,
decorateElement: true,
errorElementClass: 'errorCSS',
messagesOnModified: true,
debug: true,
grouping: {
deep: true,
observable: false //Needed so added objects AFTER the initial setup get included
},
};
ko.validation.init(validationOptions);
// define array model
var Item = function () {
var self = this;
ItemID = ko.observable();
ItemName = ko.observable().extend({
required: { message: '* item name needed' }
});
ItemPrice = ko.observable();
_destroy = false;
}
// define view model
var ViewModel = function (data) {
var self = this;
self.OrderID = ko.observable();
self.ReturnString = ko.observable();
self.CustomerName = ko.observable().extend({
required: { message: '* customer name needed' }
});
self.OrderDate = ko.observable();
self.OrderItems = ko.observableArray([]); // to be array of "Item"
// create validation group
self.orderErrors = ko.validation.group(self);
self.orderItemErrors = ko.validation.group(
self.OrderItems, { deep: true }
);
self.lineItemsValid = function () {
var LValid = false;
if (self.orderItemErrors().length > 0) {
if (self.orderItemErrors()[0] != null) // important to test for null
LValid = false;
else
LValid = true;
}
else LValid = true
if (LValid) {
return true
}
else
{
self.orderItemErrors.showAllMessages();
return false;
}
}
self.orderValid = function () {
var LValid = false;
if (self.orderErrors().length > 0) {
if (self.orderErrors()[0] != null) // important to test for null
LValid = false;
else
LValid = true;
}
else LValid = true
if (LValid) {
return true
}
else {
self.orderErrors.showAllMessages();
return false;
}
}
self.isValid = function () {
if(self.orderValid() & self.lineItemsValid()){
alert('All ok!')
}
else{
alert('Errors!');}
}
// operations
self.addLineItem = function () {
self.OrderItems.unshift(new Item());
}
self.removeLineItem = function (item) {
self.OrderItems.destroy(item);
}
// load data into model
self.loadData = function () {
ko.mapping.fromJS(modeldata, {}, self);
}
}
$(document).ready(function () {
var viewModel = new ViewModel()
ko.applyBindings(viewModel);
});
問題:
(1) クリック機能を使用して注文項目を追加することもできますが、これらのデータは監視可能な配列で更新されないようです。ただし、「削除」項目関数を呼び出すと、配列項目が削除済みとしてマークされます。
(2) マッピングを使用してアイテムをロードし、検証をテストすると (required = true)、マッピングが完了した後に追加した注文アイテムではなく、マッピングを介してロードされたアイテムに対してのみ機能します
(3)マッピングによって持ち込まれた注文アイテムを更新すると、変更はすぐにオブザーバブル配列に反映され、マッピング後に追加した注文アイテムを更新すると、配列に更新がありません。
私はここに JSFiddle を持っています:
http://jsfiddle.net/devops/ZsDjh/40/
観測可能な配列に追加する方法に関係していると確信していますが、明らかなものは何も見えません-明らかに基本的なものが欠けています...誰かアイデアがあれば?
ありがとう