使用淘汰赛验证,您可以为您的 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/
问题是,只有当您再次手动运行验证时,它才能工作一次或更好。有两个原因:
第一个是验证只会在可观察的变化时再次触发。在这种情况下,这就是 observableArray 'dataValues'。并且 observableArrays 仅在更改底层数组(即添加或删除元素)时才会更改。但它不会在元素更改时触发任何更改事件。
第二个问题是 dataValues 中的数据由纯 JavaScript 对象组成。它们不是 ko.observables。因此没有双向绑定(更新输入不会更新对象的值)。
您可以通过对数据使用 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/
或者,您可以将验证规则附加到计算的。