想象一下,我有一个像这样的数据模型:
// Pseudo-code, as I don't know how to achieve this
const Model = {
name: String.required,
description: String.optional,
rank: Number.required,
// ...
}
基本上,这意味着对象必须具有属性name
,并且必须是String
。属性description
是可选的,但是必须定义为String
。等等
现在,假设我有一堆对象:
const obj1 = {
name: 'Object 1',
rank: 1,
}
const obj2 = {
description: 'This is object 2',
rank: 2,
}
为了将我的对象保存在NoSQL数据库(Firebase的Firestore)中,我想确保每个Object
匹配 Model
。这样可以防止缺少字段。
在我的示例中,obj1
应该通过,但是obj2
应该没有name
属性。
有没有办法抛出错误消息,其中缺少哪些属性?
答案 0 :(得分:0)
您可以创建一个简单函数,该函数将基于一组必需和可选参数来验证您的模型。
注意:以下内容在函数中硬编码了required
和optional
参数,但是您也可以毫不费力地传递它们并更改代码。只需删除声明并将它们作为参数添加到函数中即可。
function validateModel(obj) {
let
// parameters specification
required = ["name", "rank"],
optional = ["description"],
// helper methods
toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
grab = (type) => type.reduce(toObjects, {}),
payload = () => Object.assign(grab(required), grab(optional)),
notValid = v => !Reflect.has(obj, v);
//output
if (required.some(notValid)) return false;
return payload();
}
//setup
let log = (x) => { return console.log(x), log };
const Model={name:"n",description:"d",rank:"r"},Model2={rank:"a"},Model3={rank:"b",name:"b"};
// Validation Method:
function validateModel(obj) {
let
// parameters specification
required = ["name", "rank"],
optional = ["description"],
// helper methods
toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
grab = (type) => type.reduce(toObjects, {}),
payload = () => Object.assign(grab(required), grab(optional)),
notValid = v => !Reflect.has(obj, v);
//output
if (required.some(notValid)) return false;
return payload();
}
// Examples:
log
(validateModel(Model) || "Invalid Model")
(validateModel(Model2) || "Invalid Model")
(validateModel(Model3) || "Invalid Model")
如果创建类似模型检查器的工具,最好是能够使用它检查多种类型的模型。下面的代码创建一个构造函数,该构造函数采用充满结构的Object。每个结构都包含required
和optional
参数的数组。
ModelChecker
构造函数使用单个方法validate
返回一个对象。通过传入要检查的对象和要检查的模型结构的名称,可以确定模型是否有效。
//setup
let log = (x) => { return console.log(x), log };
const Model={name:"n",description:"d",rank:"r"},Model2={rank:"a"},Model3={rank:"b",name:"b"}, Car={"color":"black", "name": "toyota" }, Car2={"name":"chevy"};
//setup validation structures
const structs = {
"identity": {
required: ["name", "rank"],
optional: ["description"]
},
"car": {
required: ["color"],
optional: ["name"]
}
}
// model checker constructor
function ModelChecker(structs) {
let proto = {
structs
};
proto.validate = function validateModel(obj, struct) {
if (!this.structs[struct]) return false;
let
// parameters specification
required = this.structs[struct].required,
optional = this.structs[struct].optional,
// helper methods
toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
grab = (type) => type.reduce(toObjects, {}),
payload = () => Object.assign(grab(required), grab(optional)),
notValid = v => !Reflect.has(obj, v);
//output
if (required.some(notValid)) return false;
return payload();
}
return proto;
}
// Examples:
let mc = ModelChecker(structs);
log
(mc.validate(Model, "identity") || "Invalid Model")
(mc.validate(Model2, "identity") || "Invalid Model")
(mc.validate(Model3, "identity") || "Invalid Model")
(mc.validate(Car, "car") || "Invalid Model")
(mc.validate(Car2, "car") || "Invalid Model")