具有动态可观测性的KnockoutJS验证
KnockoutJS Validation with dynamic observables
我正在使用这个插件https://github.com/ericmbarnard/Knockout-Validation我正在尝试验证一个动态加载的对象。
Javascript:
function VM() {
var self = this;
// This is a static observable, just to ensure that basic validation works fine.
self.static = ko.observable();
self.static.extend({required: true});
// This is the observable that will be updated to my model instance.
self.person = ko.observable({});
// This is an handler for manual trigger.
// I'm not even sure this is needed.
self.a = function(){
self.errors.showAllMessages();
self.staticErrors.showAllMessages();
}
// Here i'm loading current person from somewhere, i.e. a rest service.
self.load = function() {
// Update observable
self.person(new Model());
// Define validation rules
self.person().name.extend({required: true});
self.person().email.extend({required: true});
// Set person data
self.person().name('Long');
self.person().email('John');
// Set validators
self.errors = ko.validation.group(self.person);
self.staticErrors = ko.validation.group(self.static);
}
}
// Just a test model.
function Model() {
this.name = ko.observable();
this.email = ko.observable();
}
ko.validation.init();
var vm = new VM();
ko.applyBindings(vm);
标记
<ul>
<li>1. Hit "Load"</li>
<li>2. Hit "Show errors", or maunally change input data.</li>
</ul>
<button data-bind='click: load'>Load</button>
<br/>
<h1>This is working properly.</h1>
<input type='text' data-bind='value: static' />
<br/>
<h1>This is not working.</h1>
<input type='text' data-bind='value: person().name' />
<input type='text' data-bind='value: person().email' />
<br/>
<button data-bind='click: a'>Show errors</button>
Fiddlehttp://jsfiddle.net/qGzfr/
我该如何做到这一点?
只有当Knockout解析绑定时,您的属性已验证,验证插件才会应用于绑定中。
换句话说:在属性绑定到UI之后,您不能向属性添加验证。
在您的示例中,您使用self.person = ko.observable({});
中的一个空对象作为默认值,因此当Knockout执行data-bind='value: person().name'
表达式时,您没有name
属性,因此即使您稍后将name
属性添加到对象中,验证也不会起作用。
在您的示例中,您可以通过更改Model
构造函数以包含验证规则来解决此问题:
function Model() {
this.name = ko.observable().extend({required: true});
this.email = ko.observable().extend({required: true});
}
并使用一个空的Model
对象作为默认人:
self.person = ko.observable(new Model());
调用Load
时,不要替换person
对象,而是更新其属性:
self.load = function() {
// Set person data
self.person().name('Long');
self.person().email('John');
}
演示JSFiddle
注意:如果像self.person(new Model());
那样替换整个对象,Knockout并不总是能很好地处理,所以只更新属性而不丢弃整个对象是更好的做法。
不同的解决方案是使用with
绑定,因为在with
绑定内部,如果绑定属性发生更改,KO将重新评估绑定。
所以改变你的看法:
<!-- ko with: person -->
<input type='text' data-bind='value: name' />
<input type='text' data-bind='value: email' />
<!-- /ko -->
在这种情况下,您需要使用null
作为默认person
:
self.person = ko.observable();
在您的Load
中,您需要在分配person
属性之前添加验证,因此在KO应用绑定时,您的属性已进行验证:
self.load = function() {
var model = new Model()
model.name.extend({required: true});
model.email.extend({required: true});
self.person(model);
// Set person data
self.person().name('Long');
self.person().email('John');
}
演示JSFiddle
我能够让它工作,这是所需的更改:
<head>
<script type="text/javascript" src ="knockout-2.3.0.js"></script>
<script type="text/javascript" src ="knockout.validation.min.js"></script>
</head>
<body>
<!-- no changes -->
<script>
function VM() { ... }
function Model() { ... }
// ko.validation.init();
var vm = new VM();
ko.applyBindings(vm);
</script>
</body>
做了什么?
- 包括KnockoutJS和验证插件
- 添加元素后绑定。请记住,HTML页面是从上到下解析的
你怎么知道?控制台中出现以下错误:
无法读取空的属性"nodetype"
和
无法调用未定义的方法"group"
- 正在验证8个真/假复选框或复选框中的2个
- knockoutjs可观察数组
- 借助asp.net验证或java脚本对多个文本进行验证
- jQuery自定义验证比较多个输入的序列
- 使用html中的外部javascript进行数据验证
- 如何使用jquery Validation验证Formspread
- jquery中的文本框验证
- 在验证和发送邮件后更改联系人表单的 html
- 代码不会验证
- KnockoutJS-组件-多个实例
- JS验证ajax返回的html中的表单数据
- 同步调用,直到用户通过angular验证为访问者
- 具有动态可观测性的KnockoutJS验证
- 用于使用 KNOCKOUTJS 验证输入文本框中非英语字符的自定义规则
- 在 applyBindings (init/onload) 期间停止 Knockoutjs 验证
- Knockoutjs验证多个表单
- knockoutJS中的验证代码不起作用
- 使用KnockoutJS进行多字段验证的最佳实践
- JQuery表单验证我需要一个点击事件在knockoutjs验证表单
- Knockoutjs验证-重新计算验证规则