在Autoform中使用对象作为选项

时间:2016-08-06 17:39:23

标签: mongodb meteor meteor-autoform meteor-collection2 simple-schema

在我的Stacks架构中,我定义了dimensions属性:

dimensions: {
    type: [String],
    autoform: {
        options: function() {
            return Dimensions.find().map(function(d) {
                return { label: d.name, value: d._id };
            });
        }
    }
}

这非常有效,并且使用Mongol我能够看到通过表单插入数据的尝试运行良好(在这种情况下,我选择了两个要插入的维度)

Mongol image

然而,我真的是存储实际维度对象而不是密钥的数据。像这样:

[Mongol good[2]

为了尝试实现这一目标,我将type:[String]更改为type:[DimensionSchema],将value: d._id更改为value: d。这里的想法是我告诉表格我期待一个对象并且现在正在返回对象本身。

然而,当我运行此操作时,我在控制台中收到以下错误。

  

Meteor目前不支持ObjectID以外的对象作为ids

稍微调整并将type:[DimensionSchema]更改为type: DimensionSchema我在控制台中看到了一些新错误(可能是type是数组时会被掩埋

console image

所以似乎autoform试图获取我想要存储在数据库中的值并尝试将其用作id。关于最佳方法的任何想法?。

此处参考的是我的DimensionSchema

export const DimensionSchema = new SimpleSchema({
    name: {
        type: String,
        label: "Name"
    },
    value: {
        type: Number,
        decimal: true,
        label: "Value",
        min: 0

    },
    tol: {
        type: Number,
        decimal: true,
        label: "Tolerance"
    },
    author: {
        type: String,
        label: "Author",
        autoValue: function() {
            return this.userId
        },
        autoform: {
            type: "hidden"
        }
    },
    createdAt: {
        type: Date,
        label: "Created At",
        autoValue: function() {
            return new Date()
        },
        autoform: {
            type: "hidden"
        }
    }
})

2 个答案:

答案 0 :(得分:1)

根据我的经验并在this issue中自我测试,autoform对于作为对象数组的字段不是很友好。

我通常建议不要以这种方式嵌入这些数据。如果将来修改dimension文档,则会使数据难以维护。

替代方案

  • 您可以使用publish-composite这样的包在发布中创建反应式连接,而只在_id文档中嵌入stack
  • 您可以使用类似PeerDB包的内容为您执行反规范化,这也将为您更新嵌套文档。考虑到它带有学习曲线。
  • 手动编码使用AutoForm无法轻松创建的特定表单。这为您提供了最大程度的控制,有时它比所有的修补更容易。

如果您坚持使用AutoForm

虽然可以create a custom input type(通过AutoForm.addInputType()),但我不推荐它。它需要您创建模板并在其valueOut方法中修改数据,并且生成编辑表单并不容易。

由于这是一个特定的用例,我认为最好的方法是使用稍微修改后的架构并使用 Meteor方法处理数据。

使用字符串数组定义架构:

export const StacksSchemaSubset = new SimpleSchema({
  desc: {
    type: String
  },
  ...
  dimensions: {
    type: [String],
    autoform: {
      options: function() {
        return Dimensions.find().map(function(d) {
            return { label: d.name, value: d._id };
        });
      }
    }
  }
});

然后,渲染一个quickForm,指定一个模式和一个方法:

<template name="StacksForm">

  {{> quickForm
    schema=reducedSchema
        id="createStack"
        type="method"
        meteormethod="createStack"
        omitFields="createdAt"
  }}

</template>

定义适当的帮助程序以提供架构:

Template.StacksForm.helpers({
  reducedSchema() {
    return StacksSchemaSubset;
  }
});

在服务器上,定义方法并在插入之前改变data

Meteor.methods({
  createStack(data) {
    // validate data
    const dims = Dimensions.find({_id: {$in: data.dimensions}}).fetch(); // specify fields if needed
    data.dimensions = dims;
    Stacks.insert(data);
  }
});

答案 1 :(得分:0)

此时我唯一可以建议的(如果值不支持object类型),就是将对象转换为string(即序列化字符串)并将其设置为“维度”的值“键(而不是对象)并将其保存到DB中。

从db返回时,只需将该值(string)重新序列化为object