javascript - 使用动态可观察对象进行 KnockoutJS 验证

标签 javascript knockout.js knockout-validation

我正在使用这个插件 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>

fiddle http://jsfiddle.net/qGzfr/

我如何使它工作?

最佳答案

验证插件仅在您的绑定(bind)被 Knockout 解析时应用到您的绑定(bind)中。

换句话说:您不能在属性绑定(bind)到 UI 后向该属性添加验证。

在您的示例中,您在 self.person = ko.observable({}); 中使用一个空对象作为默认值,因此当 Knockout 执行 data-bind=' value: person().name' expression 您没有 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 绑定(bind),因为在 with 绑定(bind)内部,如果绑定(bind)属性发生变化,KO 将重新评估绑定(bind)。

所以改变你的看法:

<!-- 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 应用您的属性具有的绑定(bind)时验证:

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 .

关于javascript - 使用动态可观察对象进行 KnockoutJS 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20586950/

相关文章:

javascript - angularjs 的 ng 映射中的距离

javascript - Javascript 中的空数组值

javascript - knockoutjs 的数据加载模式

knockout.js - 自定义 knockout validation 3 参数

javascript - 按 Angular ng-repeat 中的行限制文本大小

javascript - 在 Node JS 中导出一个类

c# - 获取 knockout 模型中的 MVC Person 模型书籍列表(可观察数组)

javascript - 使用 jQote2 的 knockout 模板

knockout.js - ko.validation with validatedObservable 给我奇怪的结果

knockout-validation - 具有淘汰验证功能的淘汰赛剑道小部件不起作用