ノックアウト検証を使用して、observableArray のルールを作成できます。
var data = [
{ StepNo: 1, Details: "test1", Address: "address1" },
{ StepNo: 1, Details: "test2", Address: "address2" },
{ StepNo: 3, Details: "test3", Address: "address3" },
{ StepNo: 4, Details: "test4", Address: "address4" },
];
function UniqueViewModel(initialData) {
var self = this;
self.dataValues = ko.observableArray(initialData).extend({
validation: {
validator: function (val, someOtherVal) {
var sorted = val.sort(function (a, b) {
return a.StepNo - b.StepNo;
}), max = val.length;
for(var i = 0; i < max; i++) {
if(sorted[i].StepNo !== i+1) {
return false;
}
}
return true;
},
message: 'Your error message.',
params: true
}
});
}
var viewModel = new UniqueViewModel(data);
// show error
viewModel.dataValues.isModified(true);
ko.applyBindings(viewModel);
そして、次の方法でメッセージをどこかに表示できます。
<p data-bind="validationMessage: dataValues"></p>
フィドル: http://jsfiddle.net/delixfe/AUYhy/
問題は、検証を手動で再度実行した場合にのみ、1 回またはそれ以上にしか機能しないことです。2 つの理由があります。
1 つ目は、オブザーバブルが変更された場合にのみ検証が再度トリガーされることです。その場合、それは observableArray 'dataValues' です。また、observableArrays は、基になる配列を変更する場合、つまり要素を追加または削除する場合にのみ変更されます。ただし、要素が変更されても変更イベントは発生しません。
2 つ目の問題は、dataValues のデータがプレーンな JavaScript オブジェクトで構成されていることです。それらは ko.observables ではありません。したがって、双方向バインディングはありません (入力を更新しても、オブジェクトの値は更新されません)。
2 番目の問題は、データに ko.observable を使用して解決できます。
var data = [
{ StepNo: ko.observable(1), Details: "test1", Address: "address1" },
{ StepNo: ko.observable(1), Details: "test2", Address: "address2" },
{ StepNo: ko.observable(3), Details: "test3", Address: "address3" },
{ StepNo: ko.observable(4), Details: "test4", Address: "address4" }
];
最初の問題を解決するには、observableArray と StepNo の変更に対応する必要があります。したがって、ko.computed を使用できます。
function UniqueViewModel(initialData) {
var self = this;
self.dataValues = ko.observableArray(initialData);
self.dataValuesStepsValid = ko.computed(function () {
// the call to self.dataValues() subscribes to the observableArray
// and the call to element.StepNo() inside the mapping to each element
var numbers = ko.utils.arrayMap(self.dataValues(), function (element) {
return element.StepNo();
});
var max = numbers.length;
numbers.sort(function (a, b) {
return a - b;
});
for (var i = 0; i < max; i++) {
// when changing the data in the table we get strings
if (numbers[i] != i + 1) {
return false;
}
}
return true;
});
}
var viewModel = new UniqueViewModel(data);
ko.applyBindings(viewModel);
次のようなメッセージを表示できます。
<p data-bind="ifnot: dataValuesStepsValid">Your error message</p>
次のフィドルは次のことを示しています: http://jsfiddle.net/delixfe/UzDZd/
または、検証ルールを計算済みにアタッチすることもできます。