res.render не загружает sequelize datavalue - PullRequest
0 голосов
/ 17 марта 2019

Итак, я пытаюсь добавить свойство к экземпляру модели.Как упомянуто здесь Добавить свойство к объекту, которое возвращается Sequelize FindOne и документами sequelize.Добавление свойства с использованием setDataValue() будет работать.

Рассмотрим этот пример.

instance = await model.findOne({where: ...})
newColumnValue = instance.definedColumn * 15;
instance.setDataValue("newColumn", newColumnValue);

//calling data through json
//this works fine
res.json({data: instance});

Я вижу мой новый столбец и его значение с кодом выше.Тем не менее, я хочу сделать шаблон моего руля.Итак, я делаю ...

res.render("hbsFile", {data: instance});

И в моем файле .hbs кажется, что он не может прочитать newColumn, используя {{data.newColumn}}

Однако, если я сделаю это

Обходной путь 1

//transform my instance to JSON
instance.setDataValue("newColumn", newColumnValue);
instance = instance.get({plain: true});
res.render("hbsFile", {data: instance});

Обходной путь 2

//instead of using setDataValue
//associate property like in POJO
instance.newColumn = newColumnValue;
res.render("hbsFile", {data: instance});

С обоими решениями я могу получить доступ к {{data.newColumn}} inмой файл .hbs.

Вопросы

Вопрос № 1: Какой обходной путь (если есть) является правильным подходом?В чем альтернатива?

Вопрос №2: Почему не выражается res.render() метод секвелирования toJSON(), как res.json() делает?

1 Ответ

2 голосов
/ 18 марта 2019

Экспресс res.json вызывает JSON.stringify(), как указано в документах , что в свою очередь вызывает экземпляр (Sequelize) toJSON.

С другой стороны, res.render вызывает app.render, что вызывает view.render, что в итоге вызывает шаблонизатор. В течение всего этого процесса различные параметры объединяются, но, как мне удалось заметить, как в коде, так и в документации, toJSON не вызывается для предоставленных вами данных. Объект просто передается в течение всего процесса шаблонизатору, и если шаблонизатор пытается получить доступ к свойству через instance['newColumn'], он может прочитать undefined, поскольку реализация setDataValue делает: instance.dataValues[key] = value.

Экземпляры Sequelize сохраняют свои значения в объекте dataValues и используют методы получения, чтобы получить значения при обращении к ним через точечную запись. Это может привести к некоторым ситуациям, когда получатель не отображается правильно или по какой-то причине не может получить форму свойства dataValues. У меня лично была эта проблема, когда я распространял объекты на новые и передавал этот новый объект куда-то еще.

Один из обходных путей, который вы всегда можете использовать, - это сделать {data: instance.dataValues} или использовать простой параметр, как вы обнаружили (который в основном делает то же самое в большинстве ситуаций, но более чист, поскольку dataValues на самом деле не предназначен для доступа). непосредственно).

Второй обходной путь - это, конечно, вызов функции toJSON самостоятельно и последующий синтаксический анализ результата в простой объект.

Оба эти подхода не только совершенно верны, но и имеют хороший дизайн, потому что вы не должны передавать «отслеживаемые» модели ORM в качестве моделей представления (что вы делаете во втором обходном пути). Это делает вашу базу данных слоями приложения, которые не должны иметь к ней доступа и могут вызвать непредвиденное поведение.

<ч />

TLDR: Обходной путь 1 - лучший подход

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...