我正在尝试使用Knockout实现验证,并尝试了#34; Bob"来自here
的示例<p data-bind="css: { error: firstName.hasError }">
<input data-bind='value: firstName, valueUpdate: "afterkeydown"' />
<span data-bind='visible: firstName.hasError, text: firstName.validationMessage'> </span>
</p>
<p data-bind="css: { error: lastName.hasError }">
<input data-bind='value: lastName, valueUpdate: "afterkeydown"' />
<span data-bind='visible: lastName.hasError, text: lastName.validationMessage'> </span>
</p>
源代码:查看模型
ko.extenders.required = function(target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();
//define a function to do validation
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
}
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
return target;
};
function AppViewModel(first, last) {
this.firstName = ko.observable(first).extend({ required: "Please enter a first name" });
this.lastName = ko.observable(last).extend({ required: "" });
}
ko.applyBindings(new AppViewModel("Bob","Smith"));
CSS:
.validationError{
border:solid 1px red;
}
在初始页面加载时,文本框中不会有任何数据。所以我删除了硬编码的名字。 现在,验证消息显示在页面加载上,而不是用户离开文本框时。 不知何故,KO在页面加载期间考虑文本框值已更改并触发验证代码。
如何阻止这种情况发生?
这是我试图尝试的用例。 我有两个文本框,一个需要显示没有消息的红色边框,另一个需要在验证时显示消息。
感谢。
答案 0 :(得分:0)
初始验证由以下行触发:
validate(target());
评论出来。
但现在,如果您输入空文本框并跳出它,则没有任何变化:焦点时该字段为空,模糊时该字段为空。因此,observable不会改变,并且不会触发订阅。
因此,您需要做的是在模糊时触发验证,而不仅仅是在更改时。您需要将验证订阅到绑定元素的blur事件以进行其他验证。但这是不可能的,因为你不能接受observable所绑定的元素。
就我能想到的解决方案而言,由于您只能访问可观察对象,因此无法通过扩展器实现您想要的效果。
您需要创建一个custom binding,以便您访问该元素。在这种情况下,您可以访问元素,值访问器(相当于扩展器的target()
)以及元素中的所有其他绑定。这是自定义绑定更新功能的签名:
function(element, valueAccessor, allBindings)
我已经创建了一个required
自定义绑定处理程序的示例实现,您可以将其用作satrting点。 Here is the fiddle,这是代码:
HTML:
<input type="text" data-bind="value: name, required: 'Name required'">
<span data-bind="visible: name.hasError, text: name.requiredMessage"></span>
<br/>
<input type="text" data-bind="value: age, required: 'Age required'">
<span data-bind="visible: age.hasError, text: age.requiredMessage"></span>
JavaScript的:
ko.bindingHandlers.required = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
console.log('Init', element);
var valueObs = allBindings.get('value');
valueObs.hasError = ko.observable(false);
valueObs.requiredMessage = ko.observable(ko.unwrap(valueAccessor()));
valueObs.firstTime = true;
$(element).blur(function() {
console.log('Blur');
valueObs.hasError(!valueObs());
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
var valueObs = allBindings.get('value');
console.log('value: ', valueObs());
if (valueObs.firstTime) {
valueObs.firstTime = false;
return;
}
valueObs.hasError(!valueObs());
}
};
var vm = {
name: ko.observable(""),
age: ko.observable("")
};
ko.applyBindings(vm);