Использование объектов в качестве параметров в автоформе

В моем Stacks схема у меня есть dimensions свойство определяется как таковое:

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

Это работает очень хорошо, и с помощью Mongol я вижу, что попытка вставить данные через форму работала хорошо (в этом случае я выбрал два измерения для вставки)

Монгольское изображение

Однако, что я на самом деле, что данные, которые хранят фактический объект измерения, а не его ключ. Что-то вроде этого:

[Монгольский хорошо [2

Чтобы попытаться добиться этого я изменил 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 снова.

Другие вопросы по тегам