Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript sailsjs:使用嵌入的JSON属性验证模型_Javascript_Sails.js - Fatal编程技术网

Javascript sailsjs:使用嵌入的JSON属性验证模型

Javascript sailsjs:使用嵌入的JSON属性验证模型,javascript,sails.js,Javascript,Sails.js,如何验证Sails JS中object类型属性的模型 我知道带有简单值(例如字符串)的属性是可以接受的,但是这对于嵌套的JSON是如何工作的呢 例如: { name: 'John', location: { x: 23, y: 15, z: 50 } } 那么它的形式是: { name: { type: 'string', required: true, }, loc

如何验证Sails JS中object类型属性的模型

我知道带有简单值(例如字符串)的属性是可以接受的,但是这对于嵌套的JSON是如何工作的呢

例如:

{
    name: 'John',
    location: {
        x: 23,
        y: 15,
        z: 50
    }
}
那么它的形式是:

{
    name: {
        type: 'string',
        required: true,
    },
    location: {
        x: {
            type: 'number',
            required: true
        },
        y: {
            type: 'number',
            required: true
        },
        z: {
            type: 'number',
            required: true
        }
    }
}
Waterline(Sails ORM)不直接支持嵌套模式。您可以改为使用验证属性:

module.exports = {

  types: {
    location: function(val) {
      // Make sure that x, y and z are present and are numbers.
      // This won't allow numeric strings, but you can adjust to fit your needs.
      return (_.isNumber(val.x) && _.isNumber(val.y) && _.isNumber(val.z));
    }
  },

  attributes: {

    location: {
      type: 'json',
      required: true, // If you want the whole attribute to be required
      location: true  // Validate that the attribute has the schema you want
    }

    ...more attributes...

  }

};

到目前为止,我找到的最优雅的解决方案是使用“机器”库(它为sailsjs中的操作提供了动力,由sailsjs人员构建)来定义类型验证“机器”

首先,您需要一个类型定义帮助器:

$ cat api/types/define.js 
const buildWithCustomUsage = require("machine").buildWithCustomUsage;

function validateWith(machine, inputs) {
    machine(inputs).now();
    return true;
}

module.exports = function (def) {
    const machine = buildWithCustomUsage({
        def,
        extraArginsTactic: "doNotCheck"
    });
    return {
        machine,
        validate: validateWith.bind(null, machine)
    };
};
然后可以定义如下类型:

$ cat api/types/QuoteRequest.js 
module.exports = require("./define")({

    description: "Quote request type definition",

    inputs: {
        input_currency_type: {
            description: "Input currency type",
            type: "string",
            required: true
        },
        amount_requested: {
            description: "Requested amount in input currency",
            type: "string",
            required: true
        }
    },

    sync: true,

    fn: function (inputs, exits) {
        // your other validation logics
        return exits.success();
    }
});
inputs: {
    request: {
        type: "json",
        required: true,
        custom: require("../../types/QuoteRequest").validate
    }
},
您需要确保设置了
sync:true

要在控制器中使用它,请执行以下操作:

$ cat api/types/QuoteRequest.js 
module.exports = require("./define")({

    description: "Quote request type definition",

    inputs: {
        input_currency_type: {
            description: "Input currency type",
            type: "string",
            required: true
        },
        amount_requested: {
            description: "Requested amount in input currency",
            type: "string",
            required: true
        }
    },

    sync: true,

    fn: function (inputs, exits) {
        // your other validation logics
        return exits.success();
    }
});
inputs: {
    request: {
        type: "json",
        required: true,
        custom: require("../../types/QuoteRequest").validate
    }
},

希望有帮助

我做了一个结构比较函数来处理这种情况,我想和大家分享一下,希望能给大家带来启发和帮助:

假设您使用的是sails v1

使用以下代码在
/api/services
中创建名为
ModelService.js
的文件:

module.exports = {
  invalidStructure(schema, input) {
    try {
      if (schema.type === 'array') {
        // Invalid: if input is not array
        //  OR some of input[items] doesn't match schema.item
        return !_.isArray(input) ||
          _.some(input, item => this.invalidStructure(schema.item, item));
      }
      else if (schema.type === 'object') {
        // Invalid if input is not an object
        //  OR if input.keys doesn't match schema.struct.keys
        //  OR if typeof input[key] doesn't match schema.struct[key]
        return !_.isObjectLike(input) ||
          !_.isEqual(_.keys(schema.struct), _.keys(input)) ||
          _.some(_.keys(input), key => this.invalidStructure(schema.struct[key], input[key]));
      }
      else { // verifying field value vs schema.type
        // TODO: Add other field validations here (i.e. isEmail, required,...etc.)
        return typeof input !== schema.type;
      }
    }
    catch (err) {
      sails.log.error('Exception in [invalidStructure] : ', err);
      return true;
    }
  }
}
并在您的模型中这样使用:

const address = {
  type: 'object',
  struct: {
    name: { type: 'string' },
    location: {
      type: 'object',
      struct: {
        x: { type: 'string' },
        y: { type: 'string' },
        z: { type: 'string' },
      }
    }
  }
}
module.exports = {
  attributes: {
    address: {
      type: 'json',
      custom: value => !ModelService.invalidStructure(address, value)
    }
  }
}
现在我知道这不适用于任何情况(即
必需:false

但它应该可以让您使用匹配的
json
结构和值类型


注意:这是最重要的。请随意使用或增强PR

我想使用验证规则,如
waterlineSchema:true
来使用所有支持的类型和来自sails/waterline的验证。有什么提示吗?图书馆?