Knockout.js 根据某个条件验证可观察性
我正在尝试,看看是否有任何聪明的解决方案来创建定制验证器,这些验证器可以抽象为整洁和重用 在下面的jsfiddle中,我只是建立了一个简单的父模型,用于存储度量值和度量值数组(只是一个值和一个日期)。在这个例子中,我提出了两个要求Knockout.js 根据某个条件验证可观察性,knockout.js,knockout-validation,Knockout.js,Knockout Validation,我正在尝试,看看是否有任何聪明的解决方案来创建定制验证器,这些验证器可以抽象为整洁和重用 在下面的jsfiddle中,我只是建立了一个简单的父模型,用于存储度量值和度量值数组(只是一个值和一个日期)。在这个例子中,我提出了两个要求 每个测量都提供了两个字段,或者两个字段都不必提供 必须至少有一个有效(满足先前条件)测量值 在父数组中 理想情况下,我希望将定义有效的验证逻辑存储在度量对象中,如下所述。但是,我非常厌恶的是我必须在atlestone()中的父模型中执行的“动手”验证 敲除验证将自动验
atlestone()
中的父模型中执行的“动手”验证HasValues
方法???也就是说,我想将搜索“至少一个”的概念抽象到一个定制的验证器中,该验证器可以为我处理这项工作,然后告诉这个验证器“嘿,这是我希望您用来验证数组中每个项的函数。”
提前谢谢
function Model(data)
{
var self = this;
self.Measurements = ko.observableArray();
for(var i = 0; i < data.length; i++)
self.Measurements.push(new Measurement(data[i]));
function hasAtLeastOne(){
var atLeastOne = false;
$.each(self.Measurements(), function(i, item) {
if (item.HasValues()) {
atLeastOne = true;
return;
}
});
return atLeastOne;
}
self.Save = function() {
if (self.canSave() && atLeastOne())
alert('save');
else
alert('arg!');
};
self.errors = ko.validation.group(self);
self.canSave = ko.computed(function() {
return self.errors().length == 0;
});
}
function Measurement(data)
{
var self = this;
self.Value = ko.observable(data.val);
self.Date = ko.observable(data.date);
self.Value.extend({ required: { onlyIf: isRequired }, number: true });
self.Date.extend({ required: { onlyIf: isRequired }, date: true });
self.HasValues = function() {
return ko.utils.isNotNullUndefOrEmpty(self.Value()) &&
self.Date() && self.Date().length > 0;
};
function isRequired() {
return ko.utils.isNotNullUndefOrEmpty(self.Value()) ||
(self.Date() && self.Date().length > 0);
}
}
ko.utils.isNotNullUndefOrEmpty = function (value) {
return (typeof value === 'string' && value.length > 0) ||
(typeof value !== 'string' && value);
};
功能模型(数据)
{
var self=这个;
自我测量=ko.observearray();
对于(变量i=0;i0;
};
函数isRequired(){
返回ko.utils.isNotNullUndefOrEmpty(self.Value())||
(self.Date()和&self.Date().长度>0);
}
}
ko.utils.isNotNullUndefOrEmpty=函数(值){
返回(typeof value=='string'&&value.length>0)|
(值的类型!='string'&&value);
};
下面是一个可以使用的JSFIDLE,它有我的示例:
我一直在找图书馆的资料来源,看看是否能找到一些可行的选择。这是我到目前为止发现的 两种不同的选择都有优点/缺点(当然): 使用自定义验证器:
ko.validation.rules['AtLeastOne'] = {
validator: function (array, predicate) {
var self = this;
self.predicate = predicate;
return ko.utils.arrayFirst(array, function (item) {
return self.predicate.call(item);
}) != null;
},
message: 'The array must contain at least one valid element.'
};
function Modal() {
var self = this;
self.Measurements = ko.observableArray().extend({ AtLeastOne: function () {
return this && this.HasValues();
}
...//refer to OP
...
...
self.Save() = function() {
if (self.errors().length == 0)
alert('Everything is valid, we can save!');
else if (!self.Measurements.isValid())
alert('You must have at least one valid item in the pot!');
};
});
var KoValidationFactory = {
AtLeastOne: function (measurements, validator) {
return function () {
var self = this;
self.validator = validator;
return ko.utils.arrayFirst(measurements, function (measurement) {
return self.validator.call(measurement);
}) != null;
};
}
};
function Modal() {
var self = this;
self.Measurements = ko.observableArray();
...//refer to OP
...
...
self.Save = function () {
var atLeastOneArrayValidator = KoValidationFactory.AtLeastOne(self.Measurements(), function () {
return this && this.HasValues();
});
var arrayWasValid = atLeastOneArrayValidator();
if (arrayWasValid && self.errors() == 0)
alert('everything is good, we can save');
else if (!arrayWasValid)
alert('You must have at least one item in the pot!');
};
}
这种方法几乎使程序员不再需要验证,而且非常可重用。但是,我注意到一个潜在的缺点是,每当数组中存储的任何值(对象或其他对象)发生变化时,它都会调用自定义验证规则。对大多数人来说可能不是问题
使用验证器工厂:
ko.validation.rules['AtLeastOne'] = {
validator: function (array, predicate) {
var self = this;
self.predicate = predicate;
return ko.utils.arrayFirst(array, function (item) {
return self.predicate.call(item);
}) != null;
},
message: 'The array must contain at least one valid element.'
};
function Modal() {
var self = this;
self.Measurements = ko.observableArray().extend({ AtLeastOne: function () {
return this && this.HasValues();
}
...//refer to OP
...
...
self.Save() = function() {
if (self.errors().length == 0)
alert('Everything is valid, we can save!');
else if (!self.Measurements.isValid())
alert('You must have at least one valid item in the pot!');
};
});
var KoValidationFactory = {
AtLeastOne: function (measurements, validator) {
return function () {
var self = this;
self.validator = validator;
return ko.utils.arrayFirst(measurements, function (measurement) {
return self.validator.call(measurement);
}) != null;
};
}
};
function Modal() {
var self = this;
self.Measurements = ko.observableArray();
...//refer to OP
...
...
self.Save = function () {
var atLeastOneArrayValidator = KoValidationFactory.AtLeastOne(self.Measurements(), function () {
return this && this.HasValues();
});
var arrayWasValid = atLeastOneArrayValidator();
if (arrayWasValid && self.errors() == 0)
alert('everything is good, we can save');
else if (!arrayWasValid)
alert('You must have at least one item in the pot!');
};
}
这种方法可以确保仅在显式选择验证整个阵列时才进行验证。不利的一面是,您有更多的实际工作,它没有充分利用淘汰验证库。您必须特别验证数组和采用这种方法的任何/所有其他观测值,如果有很多,它们可能会变得混乱
我鼓励对这些方法进行编辑并提出建议