Использование объектов в качестве параметров в автоформе
В моем Stacks
схема у меня есть dimensions
свойство определяется как таковое:
dimensions: {
type: [String],
autoform: {
options: function() {
return Dimensions.find().map(function(d) {
return { label: d.name, value: d._id };
});
}
}
}
Это работает очень хорошо, и с помощью Mongol я вижу, что попытка вставить данные через форму работала хорошо (в этом случае я выбрал два измерения для вставки)
Однако, что я на самом деле, что данные, которые хранят фактический объект измерения, а не его ключ. Что-то вроде этого:
[
Чтобы попытаться добиться этого я изменил type:[String]
в type:[DimensionSchema]
а также value: d._id
в value: d
, Думая здесь, что я говорю форме, что я ожидаю объект, и теперь возвращаю сам объект.
Однако, когда я запускаю это, я получаю следующую ошибку в моей консоли.
Meteor в настоящее время не поддерживает объекты, отличные от ObjectID, в качестве идентификаторов
Ковыряюсь немного и меняюсь type:[DimensionSchema]
в type: DimensionSchema
Я вижу некоторые новые ошибки в консоли (по-видимому, они скрываются, когда type
это массив
Таким образом, создается впечатление, что автоформа пытается получить значение, которое я хочу сохранить в базе данных, и использовать его в качестве идентификатора. Есть какие-нибудь мысли о том, как сделать это лучше?
Для справки вот мой 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 ответа
Согласно моему опыту и самому себе в этом вопросе, автоформа не очень удобна для полей, которые являются массивами объектов.
Я бы вообще не советовал встраивать эти данные таким образом. Это усложняет ведение данных в случае dimension
документ будет изменен в будущем.
альтернативы
- Вы можете использовать такой пакет, как publish-смесь, чтобы создать реактивное соединение в публикации, в то же время только встраивая
_id
вstack
документы. - Вы можете использовать что-то вроде пакета PeerDB, чтобы выполнить для вас отмену нормализации, которая также обновит вложенные документы для вас. Примите во внимание, что это идет с кривой обучения.
- Вручную закодируйте конкретные формы, которые не могут быть легко созданы с помощью AutoForm. Это дает вам максимальный контроль, а иногда это проще, чем все возиться.
если вы настаиваете на использовании автоформ
Хотя может быть возможно создать пользовательский тип ввода (через 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);
}
});
Единственное, что я могу посоветовать в данный момент (если значения не поддерживают object
тип), для преобразования объекта в string
(т. е. сериализованная строка) и установите его в качестве значения для ключа "размеры" (вместо объекта) и сохраните его в БД.
И, возвращаясь из БД, просто удалите сериализацию этого значения (string
) в object
снова.