【问题标题】:How to verify an observable object have all the required members?如何验证可观察对象是否具有所有必需的成员?
【发布时间】:2014-06-02 22:26:16
【问题描述】:

基本上我想在应用绑定之前验证我的 observable,这样我就永远不会得到某事未定义错误。

假设我确实有一个 javascript 类,它定义了我需要的所有内容,并且我想针对它验证从 ajax 创建的 observable。

有通用的方法吗?

编辑:

http://jsfiddle.net/rgneko/GuR8v/

目前演示会抛出错误,因为其中一项没有 id 属性。我想验证是否所有项目都有效。

$(document).ready(function () {
    function ModelToTestAgainst(id, name, type, items) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.items = items;
    }
    var data = {
        items: [{
            id: 1,
            name: 'name1',
            type: 'folder',
            items: []
        }, {
            id: 2,
            name: 'name2',
            type: 'file',
            items: []
        }, {
            name: 'name2',
            type: 'file',
            items: []
        }]
    };
    var someRandomObservaleIGotFromWherever = ko.mapping.fromJS(data);
    // I want to Validate(someRandomObservaleIGotFromWherever) before apply bindings

    ko.applyBindings(someRandomObservaleIGotFromWherever);
});

【问题讨论】:

  • 你应该让你的问题更清楚一些,展示一些示例代码,并解释你想通用检查的内容。我们无法想象你脑子里有什么......
  • @JotaBe 我添加了小提琴。希望它解释得更好。
  • JSON Schema 越来越受欢迎。也许您可以尝试通过已知模式验证数据。 (github.com/geraintluff/tv4) 是一个正在积极开发中的库,你可以试试

标签: javascript json knockout.js validation jsonschema


【解决方案1】:

有一个标准的 JSON Schema,在 http://json-schema.org/ 中定义。

架构可以很简单:

var schema = {"type" : "object"};

这要求值是一个对象。或者更复杂,例如来自 json-schema.org 的这个示例:

{
  "title": "Example Schema",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "description": "Age in years",
      "type": "integer",
      "minimum": 0
    }
  },
  "required": ["firstName", "lastName"]
}

这需要多个属性存在,定义它们的类型,甚至是其中一个的最小值。

然后你需要一个库,允许使用这种模式验证 JS 对象。在同一站点中,您可以找到a list of libraries for validating (and parsing, creating documentation...)。请注意,并非所有库都已更新,并且并非所有库都支持最新的 JSON 架构版本。

例如using JSV,你可以像这样简单地进行验证:

var report = env.validate(json, schema);

【讨论】:

  • 谢谢!我记得前段时间读过这个。这正是我想要的!
【解决方案2】:

您为什么不将其映射/包装到您知道具有您需要的所有属性的视图模型中?

function ViewModel(model) {
    this.x = ko.observable(model.x || 0);
    this.y = ko.observable(model.y || 0);
}
var original = { x: 27 }; // Use your ajax object here.
var viewModel = new ViewModel(original);

【讨论】:

  • 在某些情况下,我只是从任何地方获取我的 observable 并且无法修改它,因为它与代码的其他部分共享。我想我能做的最好的事情就是在 observable 上创建一个包装器,但我认为这有点麻烦,而且就我而言,这有点过头了。
【解决方案3】:

如何使用 JSON Schema 验证。

我使用了来自Tiny Validator 的库来启用验证。验证很容易添加为可观察的扩展

$(document).ready(function () {
    // Attach a validationSchema method to all observable types
    ko.subscribable.fn["validateSchema"] = function(schema){
        // Convert the observable back to an object literal to test.
        var source = ko.mapping.toJS(this());

        return tv4.validate(source, schema);
    };

    // Define schema for ModelToTestAgainst
    var modelSchema = {
        "$schema": "http://tempuri.org/ModelToTestAgainst",
        "title": "ModelToTestAgainst Set",
        "type": "array",
        "items": {
            "title": "ModelToTestAgainst",
            "type": "object",
            "properties" : {
                "id" : { 
                    "type": "number", 
                    "minimum" : 1
                },
                "name" : { "type": "string" },
                "type" : { "type": "string" },
                "items" : { "type" : "array" }
            },
            "required": ["id", "name", "type", "items"]
        }
    };
    function ModelToTestAgainst(id, name, type, items) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.items = items;
    }
    var data = {
        items: [{
            id: 1,
            name: 'name1',
            type: 'folder',
            items: []
        }, {
            id: 2,
            name: 'name2',
            type: 'file',
            items: []
        }, {
            name: 'name2',
            type: 'file',
            items: []
        }]
    };
    var obs = ko.mapping.fromJS(data));
    var isValid = obs.items.validateSchema(modelSchema);

    if( isValid ) {        
        ko.applyBindings(obs);
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 2013-07-01
    • 1970-01-01
    • 2012-07-09
    • 2013-07-01
    • 1970-01-01
    • 2017-09-19
    相关资源
    最近更新 更多