敲除验证会在加载数据时停止计算错误

时间:2015-09-01 13:00:28

标签: javascript jquery validation knockout.js

我正在使用表单,我正在使用knockout + knockout.validation框架。现在我坚持验证,因为它没有按预期工作。我创造了一个简单的小提琴来向你展示我的问题。

我的viewModel是一个复杂的对象,带有可观察的字段和带有验证的.extend方法。验证本身运行良好,但计算错误则不然。

在sort中,如果我在开始时将数据分配给我的viewModel,如下所示:

self.someObject = ko.observable(new SomeObject({
        id: "123",
        name: {
            en: "Initial data"
        }
    }));

一切都很好,但是对于准确数据的调用是对WebApi的asnyc调用。因此,从服务器返回时,原始对象(viewModel.someObject)将被替换。问题是,一旦替换了对象,viewModel.errors(它是验证组)就会停止跟踪错误。

您可以在JsFiddle example中看到完整的工作示例。也许我忽略了JS中的一些重要事项(我更像是一个C#人)。

这是一个大问题,因为现在我无法停止保存数据,因为我不知道是否有任何错误。

谢谢!

2 个答案:

答案 0 :(得分:2)

错误计数无法正常工作的问题出在self.callForData函数中。

self.someObject(new SomeObject({
        id: "123",
        name: {
            en: "LoadedName"
        }
    }));

你实际上用一个' new'替换someObject observable。对象实例,因此旧对象验证变为未引用。

您需要一种方法来重置当前的某个对象'使用新数据值。我已经更新了小提琴,向您展示了如何做到这一点。基本上你介绍一个'重置'对象中的一种函数,它在不创建新实例的情况下重置对象的当前状态。 示例:https://jsfiddle.net/newuserjs/ww2r6wet/

答案 1 :(得分:0)

所以我终于找到了解决方案。现在看起来很容易..

@Dandy说,当从ajax调用返回obejct时,对象会被替换。这是因为ajax调用是异步的。

所以,如果你和我处于相同的情况,你只想做一些初始加载的obeject(每页加载只读一次数据),这是一个解决方案: 在调用ko.applyBindings,ko.validation分组和包含ko.observables的对象构造函数之前,您只需要确保在javascript对象中有数据。为此,您可以使用jQuery.when(..)。done(..)。正如我发现的那样,代码在"完成"方法将在""之后的所有异步调用之后被调用。方法完成了。

我认为你现在明白这一点。在"当"方法获取对象并将其保存到js变量。在"完成"方法,从中构造新对象并调用ko.observable等,ko.applyBindings和验证分组。我创建了代码的简单示例,因此请查看它。

var user;
var viewModel;

// The User model with constructor
function User(data) {
    var self = this;

    self.username = ko.observable(data.username);
    self.address = ko.observable(data.address);
    // .. other properties
}

// UserViewModel object with constructor
function UserViewModel() {
    var self = this;

    // Make the User object from 
    self.User = ko.observable(new User(user));

    // have some other help properties here in view model
    // self.tasks = ko.computed(..); // etc..
}

// The magic
$.when(
    $.getJSON("yourUrl",
        null,
        function(data) {
            user = new User(data);
        })
).done(function () {
    // This code block will run after the async getJSON finishes

    viewModel = new UserViewModel();
    viewModel.errors = ko.validation.group(viewModel, { deep: true });

    // Activates knockout.js
    ko.applyBindings(viewModel);
});