使用Meteor单独进行表单验证

时间:2016-01-24 14:56:49

标签: meteor meteor-collection2 simple-schema

我正在使用collection2而我正试图让它来处理验证是一种特定的方式。我有一个看起来像这样的个人资料架构:

Schema.UserProfile = new SimpleSchema({
    name: {
        type: String,
        optional: false
    }
    location: {
        type: String,
        optional: true
    }
    gender: {
        type: String,
        optional: false
    }
});

Schema.User = new SimpleSchema({
    username: {
        type: String,
        optional: true
    },
    emails: {
        type: Array,
        optional: true
    },
    "emails.$": {
        type: Object
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true
    },
    roles: {
        type: [String],
        optional: true
    },
    heartbeat: {
        type: Date,
        optional: true
    }
});

Meteor.users.attachSchema(Schema.User);

现在,在我的注册表单上,我要求用户选择他们的性别,然后在他们登录后,会向用户显示一个单独的表格,询问他们的姓名和位置。这是问题所在:

注册表格有效,一切都经过保存。当他们尝试使用位置和名称保存内部表单时,虽然我收到错误:

Error invoking Method 'updateProfile': Gender is required [400]

我知道它正在发生,因为它在架构中是必需的,但我已经获得了这些信息。我怎么不要求?或者我是否为每个表单设置验证?

4 个答案:

答案 0 :(得分:3)

来自SimpleSchema docs

  

假设您有一个必需的密钥" friends.address.city"但   " friends.address"是可选的。如果" friends.address"设置在   对象你正在验证,但" friends.address.city"不是,有   验证错误。但是,如果" friends.address"那时候没有设定   " friends.address.city"没有验证错误。因为   它所属的对象不存在。

因此,错误发生是因为您在两个表单中都包含个人资料,而且个人资料在个人资料中不是可选的。我可以想出两种解决方法:

  1. 在配置文件下有其他对象,这些对象都是可选的,并且在一个上包含名称/位置的必填字段(虽然看起来位置在两个方案中可能是基于您的代码的可选项)和必要的性别字段其他。我并不特别喜欢这种解决方案,但它无法进行表单验证。

  2. 使用jQuery表单验证(我使用包themeteorchef:jquery-validation)并使配置文件中的所有字段都可选。

  3. 它看起来像SimpleSchema接受optional属性的函数,所以你可以在那里使用一些自定义逻辑 - 也许你在该函数中得到参数或上下文,这将允许你做你做的事情要什么?

  4. 希望有所帮助!

答案 1 :(得分:3)

您必须通过jquery添加验证,或者您可以使用烤面包机在客户端显示错误。 另请阅读:link

答案 2 :(得分:3)

我假设您为表单使用aldeed:autoform。在表单中使用normal type时,必须提交所有字段,甚至是已标记为必填字段的字段。有两种方法可以解决这个问题:

  • 脏方法:使用预填充值设置隐藏字段。
  • 您还可以将表单类型设置为update as seen in the doc。通过这种方式,simple-schema将验证您的newDoc已填充之前的条目,而不会尖叫。

第二个解决方案是我在大多数情况下使用的解决方案。加号autoform's hooks为您提供足够的灵活性,以适应您可能遇到的大多数用例。

答案 3 :(得分:3)

我不知道它是否是一个更优雅的解决方案,但我们已经停止将simpleSchemas附加到当前项目中的文档。

我们在每个集合的命名空间中都有不同的模式,一个用于检查插入时的用户输入,一个用于更新,另一个用于在插入新文档时填充defaultValue(可以由客户端或者服务器,在这种情况下我们不检查输入)。我们调用.validate()或.clean()取决于我们想要做什么。

聪明地使用从模式数组构建模式的可能性,我们最终不会编写更大的模式(尽管它们还有更多模式),但我们可以完全控制何时检查,以及检查哪些字段