【问题标题】:AutoForm 5.0.2 nested schema inputs required on update更新时需要 AutoForm 5.0.2 嵌套模式输入
【发布时间】:2015-05-15 01:21:18
【问题描述】:

我已经设置了模式,以便我可以拥有一组复杂的输入集。比如:

address = {
  street:{
    type: String
  },
  city: {
    type: String
  },
  active_address: {
    type: Boolean,
    optional: true
  },
  ...
}

people: {
  name:{
    type: String
  },

  address:{
    type: [address],
    optional: true,
    defaultValue: []
  }
}

这种方式添加地址是可选的,但如果您添加地址,则所有地址字段都是必需的。

这在(我相信是)版本 4.2.2 中有效。这仍然适用于insert 类型的自动表单,但不适用于update 类型的自动表单。进行更新时,除非嵌套架构中的 所有 必填字段也有效,否则不会提交任何字段。

作为参考,我正在创建这样的表单:

{{#autoForm collection="people" id=formId type="update" doc=getDocument autosave=true template="autoupdate"}}    
  {{> afQuickField name='name' template="autoupdate" placeholder="schemaLabel"}}
  {{> afQuickField name='address' template="autoupdate"}}
{{/autoForm}} 

我的模板 (autoupdate) 我复制粘贴了整个 bootstrap3 autoform 模板并重新排列了一些 html 以满足我的需要。我在更新时根据 5.0.0 更新日志尽我所能更新了这些。如果有人能想到模板中的一个属性,它可能会导致插入和更新之间的行为不一致,而在 5.0.0 中发生了变化。

更多信息

我刚刚尝试使用 5.0.2 中的 bootstrap3 模板重新创建我的所有表单模板。仍然是相同的行为。

+

我在地址架构中有一个布尔(复选框)输入。查看文档,地址数组填充有[0 : {active_address: false}]

active_address: {
  type: Boolean,
  optional: true
}

不确定这是否有帮助...

+

根据@mark 的建议,我添加了 defaultValue:[]。它解决了这个问题......有点。现在更新表单中没有“开放”的嵌套模式,并且可以更改其他值。如果您使用添加按钮将嵌套模式“添加”到表单中,则即使您未在任何字段中插入任​​何值,整个表单也将成为必需的。无论Boolean 类型输入如何,都会发生这种情况。

我可以确定嵌套模式中的Boolean 类型输入会导致整个嵌套模式成为执行插入所必需的。删除布尔输入会导致它再次可插入。因此,同样存在一个新问题。

这个新问题可以在here找到

【问题讨论】:

  • 您要更新的文档是什么样的?地址字段中有autoValue/defaultValue字段吗?
  • @mark 我没有。您是在寻找实际的示例文档还是架构?
  • @mark 引起了我的思考,所以我查看了我的文档并添加了一些信息。
  • 对,所以我认为活动地址输入是罪魁祸首。它导致 autoform 添加缺少所有必需字段(如街道和城市)的文档,这自然会导致模式验证失败。我以前没有亲自使用过布尔输入,但我怀疑 autoform 将未选中的框误认为是“假”而不是未定义。当我使用电脑时,我必须检查是否是这种情况。
  • @mark 我将设置一个测试,将该字段的输出覆盖为未定义而不是假...或者可能将其从 $set 对象中删除?我们会看到

标签: validation meteor nested schema meteor-autoform


【解决方案1】:

我认为最好的解决方案是将defaultValue: [] 添加到架构中的address 字段。您在问题中描述的行为(不允许更新)实际上是有意的 - 请继续阅读以了解原因。

问题是,这种行为只有在已经将数组表单元素添加到表单时才存在。我的意思是,如果您单击从表单中删除街道、城市等输入的减号,则更新成功,因为 AutoForm 不会将未选中的复选框误解为用户明确取消选中该框(并因此设置值到false)。将defaultValue 设置为空数组让 AutoForm 知道不显示地址表单,除非用户明确单击加号(即,他们有想要输入的地址),在这种情况下,创建街道的行为,城市等所需的字段就是你想要的。

请注意,这意味着您必须更新集合中缺少address 字段的现有文档,并将其设置为空数组。在 mongo shell 中是这样的:

db.people.update({ "address": { $exists: false } }, { $set: { "address": [] } }, { multi: true })

您可能希望首先在选择器上运行查找以确保查询正确。

编辑

如果您想要的行为是显示子表单而不使其成为必需,您可以通过使用formToDoc 挂钩并过滤掉所有仅具有的地址对象来解决复选框问题active_address 字段设置为 false(AutoForm 错误地为我们添加的字段)。

AutoForm.addHooks('yourFormId', {
  formToDoc: function (doc) {
    doc.address = _.reject(doc.address, function (a) {
      return !a.street && !a.city && !a.active_address;
    });
    return doc;
  }
});

每次验证表单时都会调用formToDoc 钩子,因此您可以使用它来修改文档以使 AutoForm 甚至永远不会知道有地址子字段,除非它的属性已经设置好了。请注意,如果您使用此解决方案,则不必如上所述添加 defaultValue: []

【讨论】:

  • 这适用于我正在尝试做的事情。我遇到了另一个问题,现在我将打开另一个问题,基本上在“插入”表单上创建一个非常相似的问题。
  • 您的新问题似乎与此问题非常相似或可能相同(显示子表单而不需要它)。我现在没有太多时间,但是当我稍后想到一些事情时,我会在这里更新。可能有一种方法可以使用自定义提交方法而不是使用内置更新表单来解决此问题。
  • @RandyHall 我添加了另一个解决方案,如果它更适合您,请告诉我。
  • 我找到了同样的解决方案!无论如何,该死的关闭。 stackoverflow.com/questions/29107559/…
  • 不错!没有注意到您发布了另一个问题。
猜你喜欢
  • 2016-02-13
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 2016-08-01
  • 2014-07-13
  • 1970-01-01
相关资源
最近更新 更多