11

我正在使用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

4 回答 4

3

来自SimpleSchema 文档

假设您有一个必需的密钥“friends.address.city”,但“friends.address”是可选的。如果在您正在验证的对象中设置了“friends.address”,但没有设置“friends.address.city”,则会出现验证错误。但是,如果未设置“friends.address”,则“friends.address.city”不会出现验证错误,因为它所属的对象不存在。

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

  1. 在配置文件下有其他对象,这些对象都是可选的,并且在一个对象上包含名称/位置的必填字段(尽管根据您的代码,在这两种情况下,位置似乎都是可选的),另一个对象是性别的必填字段。我不是特别喜欢这个解决方案,但它可以防止需要表单验证。

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

  3. 看起来 SimpleSchema 也接受该optional属性的函数,因此您可以在那里使用一些自定义逻辑 - 也许您在该函数中获得参数或上下文,可以让您做您想做的事?

希望有帮助!

于 2016-01-26T01:41:50.370 回答
3

您必须通过 jquery 添加验证,或者您可以使用 toaster 在客户端显示错误。另请阅读:链接

于 2016-01-27T09:59:41.210 回答
3

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

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

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

于 2016-02-10T08:41:11.713 回答
3

我假设你使用aldeed:autoform你的表格。当您normal type在表格中使用时,必须提交所有字段,即使是那些已经填写且标记为必填的字段。解决此问题的两种方法:

  • 肮脏的方式:使用预填充的值设置隐藏字段。
  • 您还可以设置您的表单类型,update 如文档中所示。这样,simple-schema将验证您newDoc已经填写了以前的条目而不会尖叫。

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

于 2016-02-01T18:02:06.040 回答