Validation 使用敲除验证来验证可观察数组中的特定项
我有一个可观察的formFields数组,它被呈现到表单上的输入/选择字段列表中 每个字段都是一个单独的viewModel,并根据其自己的fieldType属性(例如-firstName、lastName、creditCardNumber等)进行渲染 在数据库中,我保留formTypes定义。对于每个表单类型,都有为此表单类型显示的所有字段的映射(例如-formType=Address将有此表单字段列表-街道、城市、国家、ZipCode等) 这样,我可以根据表单定义及其相应的表单字段动态创建不同的表单 现在,我的问题是,我想使用敲除验证来验证formFields的observableArray本身(除了每个特定的formField单独的验证,该验证工作正常)。我的意思是对具有字段间依赖关系的整个表单进行验证。例如: 银行帐户表格: 字段:分行号、账号、账户持有人姓名、银行名称 验证:(分行号+账号)*13%6==3(仅举一个例子) BranchNumber和AccountNumber字段是formFields observableArray中的field viewModels,每次observableArray中的项目发生更改时,我都需要对表单运行验证 我的问题是,当数组中的字段值更改时,字段间验证不会重新计算errors()属性 有人能帮忙吗 我自己的示例代码比我描述的要复杂得多,这就是为什么我没有在这里发布它。我希望这已经足够清楚了。谢谢Validation 使用敲除验证来验证可观察数组中的特定项,validation,knockout.js,knockout-validation,Validation,Knockout.js,Knockout Validation,我有一个可观察的formFields数组,它被呈现到表单上的输入/选择字段列表中 每个字段都是一个单独的viewModel,并根据其自己的fieldType属性(例如-firstName、lastName、creditCardNumber等)进行渲染 在数据库中,我保留formTypes定义。对于每个表单类型,都有为此表单类型显示的所有字段的映射(例如-formType=Address将有此表单字段列表-街道、城市、国家、ZipCode等) 这样,我可以根据表单定义及其相应的表单字段动态创建不同
简短示例(仅在表单初始化时调用validate,如何使其在每次ObservalArray内部项的值更改时运行):
function FormField(formField, parentForm) {
var self = this;
self.detail = ko.observable().extend({
validation: {
validator: function(val) {
isValid = false;
if (typeof self.requiredFieldType === "undefined") {
isValid = true;
} else if ([3, 5, 22].indexOf(self.requiredFieldType) > -1) { // Email, Product Account Email, Giftcard Delivery Email
isValid = val !== "" && emailPattern.test($.trim(val));
} else {
isValid = $.trim(val) !== "";
}
return isValid;
},
message: function() {
if (self.requiredFieldType === 2) {
return 'Please enter a valid Zip Code.';
} else if (self.requiredFieldType === 3 || self.requiredFieldType === 22) {
return 'Invalid Email.';
} else if (self.requiredFieldType === 5) {
return 'Invalid Account Email.';
} else if (self.requiredFieldType === 6) {
return 'Please select your iTunes store.';
} else if (self.requiredFieldType === 7) {
return 'Please enter a phone number.';
} else if (self.requiredFieldType === 9) {
return 'Please enter frequent flyer number.';
} else if (self.requiredFieldType === 10) {
return 'Please enter street.';
} else if (self.requiredFieldType === 11) {
return 'Please enter house #.';
} else if (self.requiredFieldType === 12) {
return 'Please enter city.';
} else if (self.requiredFieldType === 13 || self.requiredFieldType === 23) {
return 'Please enter country.';
} else if (self.requiredFieldType === 15) {
return 'Please enter bank account number.';
} else if (self.requiredFieldType === 16) {
return 'Please enter bank account holder name.';
} else if (self.requiredFieldType === 17) {
return 'Please enter bank name.';
} else if (self.requiredFieldType === 18) {
return 'Please enter bank branch number.';
} else if (self.requiredFieldType === 19) {
return 'Please enter first name.';
} else if (self.requiredFieldType === 20) {
return 'Please enter last name.';
} else if (self.requiredFieldType === 21) {
return 'Please select a currency.';
}
}
}
}).extend({
required: {
message: 'This field is required.'
}
});
self.requiredFieldType = formField.RequiredFieldType;
self.errors = ko.validation.group(self);
}
}
function Form(form) {
var self = this;
self.formName = form.ProductName;
self.formFields = ko.observableArray($.map(form.FormFields, function(jsonFormField) {
return new FormField(jsonFormField, self)
})).extend({
validation: {
validator: function(val) {
return false; // this is being called only once
},
message: function() {}
}
});
self.errors = ko.validation.group(self);
}
ObservalArray的验证器仅在其上存在可订阅事件时调用,该事件不包括修改所包含数组的元素。您可以告诉阵列已使用更新
self.formFields.valueHasMutated();
您需要将订阅附加到每个元素,并使订阅调用valuehassmutated
,可能类似于:
function validateParent () {
self.formFields.valueHasMutated();
}
ko.utils.arrayForEach(self.formFields(), function (item) {
item.detail.subscribe(validateParent);
});
更新:进一步调查后,我发现,其中提到了ko.validation.validateObservable()
,这似乎是一个比值发生变异更切题的选择
它们都不会导致重新计算所有字段。下面是一个包含标签和“last validated”字段的代码段,以说明在发生更改时会发生什么变化。请注意,各个字段的标签在每次更改时都会更新,但在另一个字段更改时不会更新,即使上次验证的时间随每次更改而更新
我已经注释掉了valuehassmutated
,取而代之的是validateObservable
,但它们的工作原理完全相同
vm={
lastValidated:ko.可观察(0)
};
vm.v=ko.observearray([]).extend({
验证:{
验证器:函数(val){
vm.lastValidated((new Date()).getmillizes());
}
}
});
函数addMember(名称){
var项目=可观察的ko(名称);
item.subscribe(函数(newValue){
ko.validation.validateObservable(vm.v);
//vm.v.valueHasMutated();
});
推送({
数据:项目
});
}
添加成员(“一”);
addMember('two');
ko.应用绑定(vm)代码>
恐怕我们必须查看您的数据结构才能了解其工作原理。你能把一个例子(比如你的银行账户表)浓缩到问题的最小程度吗?有时候,在做这些简单的例子时,解决方案会跳出来。@RoyJ现在好点了吗?谢谢。这会不会导致每次更改字段值时都刷新所有字段的视图?有没有一种方法可以在不刷新整个视图的情况下设置这种验证?也许是基于订阅,或者以某种方式手动强制运行验证逻辑?@UriAbramson Fair question,让我思考了一下。但不是,valueHasMutated只会导致变异的可观察对象的订户更新。请参阅更新的答案。