可以从" onblur"更改属性valueUpdate。 to" keyup"取决于属性是否附加了错误?
我想模仿jQuery验证中验证的方式,首先对模糊进行验证,然后对keyup进行验证。
这可能吗?
编辑: 让我澄清并举例说明。我不介意在" keyup"上发生对模型的绑定,我记得的是,即使有机会完成输入,也会向用户显示错误消息。相反,如果我以验证电子邮件地址为例。如果用户键入无效的电子邮件,我希望错误显示在模糊上,如果用户再次将焦点放在字段上以纠正错误,我希望错误在纠正错误后消失。另一方面,如果用户输入有效的电子邮件,然后引入错误,则应立即显示错误。
第二次编辑: 所以我已经考虑过了,我认为验证不应该干扰模型绑定,而是应该对错误消息的显示进行更改。如上所述,我希望错误在错误发生后立即出现,但只有在相关字段发生更改事件后才会出现。
我做了这个几乎的小提琴,但它应该准确显示我想要完成的事情。
http://jsfiddle.net/mntm1bne/3/
<div data-bind="validationOptions: {messageTemplate: 'myCustomTemplate'}">
<input data-bind="value: firstName, valueUpdate: 'keyup', event: {change: firstName.enableD}" />
<br />
<input data-bind="value: lastName" />
<div data-bind="if: firstName.isD">
Firstname is dirty!
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
<div data-bind="text: ko.toJSON($data)"></div>
</div>
<script type="text/html" id="myCustomTemplate">
<span data-bind="visible: field.isD && !field.isValid(), attr: { title: field.error }">X</span>
</script>
ko.extenders.trackChange = function(target, track) {
if (track) {
target.isD = ko.observable(false);
target.enableD = function() {
console.log("enable!");
target.isD(true);
}
}
return target;
};
var ViewModel = function () {
var self = this;
self.firstName = ko.observable().extend({ trackChange: true, required: { message: "firstName" }, number: true,
min: 0,
max: 100
});
self.lastName = ko.observable().extend({ required: { message: "lastName" }});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
具体来说,错误在于第一个验证消息,即在页面加载时显示。
答案 0 :(得分:0)
要正确地执行此操作,您需要重写valueUpdate
绑定以使其具有可观察性,并且您的observable将基于该值是否有错误。
这听起来很难,所以我选择了一些有点hackier的东西。我为event
替换了valueUpdate
绑定。它在keydown上触发,如果验证的变量无效,则从输入更新其值(使用event.target
)。该值将始终在模糊时更新,因此我无需处理。
var viewModel = {
num1: ko.observable(50).extend({
number: true,
min: 0,
max: 100
}),
maybeEvaluate: function(data, event) {
setTimeout(function() {
if (!viewModel.num1.isValid()) {
viewModel.num1(event.target.value);
}
}, 0);
return true;
}
};
ko.applyBindings(viewModel);
.validationMessage {
color: Red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>
0-100:
<input data-bind="value: num1, event: {keydown: maybeEvaluate}" />
<span class="validationMessage" data-bind="validationMessage: num1"></span>
<br />
<input />
这是另一种基于protected observables的方法。受保护的可观察对象的原始设计是为您提供提交或重置更改的选项。我有一个事件强制提交模糊,并且受保护被修改为在当前值无效时接收新值时自动提交。 (我不需要重置例程,因此我将其解析出来,因此请注意protectedObservable
定义是自定义的。)
更新根据您的评论(以及我没有包含所需的库),我更新了第二个示例,以便在该字段发生错误时它变得不断有效。
ko.protectedObservable = function(initialValue) {
//private variables
var _actualValue = ko.observable(initialValue),
_tempValue = initialValue,
hasHadError = false;
//computed observable that we will return
var result = ko.computed({
//always return the actual value
read: function() {
return _actualValue();
},
//stored in a temporary spot until commit
write: function(newValue) {
_tempValue = newValue;
if (!result.isValid()) {
hasHadError = true;
}
if (hasHadError) {
result.commit();
}
}
}).extend({
notify: "always"
});
//if different, commit temp value
result.commit = function() {
if (_tempValue !== _actualValue()) {
_actualValue(_tempValue);
}
};
return result;
};
var viewModel = {
num1: ko.protectedObservable(50).extend({
number: true,
min: 0,
max: 100
})
};
ko.applyBindings(viewModel);
.validationMessage {
color: Red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>
0-100:
<input data-bind="value: num1, valueUpdate: 'input', event: {blur: num1.commit}" />
<span class="validationMessage" data-bind="validationMessage: num1"></span>
<br />
<input />