node.js - res.render 不加载 Sequelize 数据值

标签 node.js express sequelize.js

所以,我想要做的是向模型实例添加一个属性。正如这里提到的 Add Property to Object that is returned by 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});

我可以使用上面的代码查看我的新列及其值。但是,我想呈现我的 Handlebars 模板。所以,我做...
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});

使用这两种解决方案,我都可以访问 .hbs 文件中的 {{data.newColumn}}

问题

问题 1:哪种 解决方法 (如果有)是正确的方法?什么是替代方案?

问题 #2:为什么不像 res.render() 那样表达 toJSON() 调用 sequelize 的 res.json() 方法?

最佳答案

Express 的 res.json 调用 JSON.stringify() ,如 docs 所述,后者又调用实例(Sequelize 的) toJSON

另一方面 res.render 调用 app.render ,后者调用 view.render ,最终调用模板引擎。在整个过程中,各种选项被合并,但据我在代码和文档中注意到,您提供的数据没有调用 toJSON 。该对象只是在整个过程中传递给模板引擎,如果模板引擎试图通过 instance['newColumn'] 访问该属性,它可能会读取 undefined 因为 setDataValue 实现: instance.dataValues[key] = value

Sequelize 的实例将它们的值存储在 dataValues 对象中,并在您通过点符号访问它们时使用 getter 来获取这些值。这可能导致某些情况下 getter 未正确映射或由于某种原因无法检索属性表单 dataValues。我个人在将对象传播到一个新对象并将该新对象传递到其他地方时遇到了这个问题。

您始终可以使用的一种解决方法是执行 {data: instance.dataValues} 或使用您发现的普通选项(在大多数情况下基本上做同样的事情,但更清晰,因为 dataValues 并不是真的打算直接访问)。

第二种解决方法当然是自己调用 toJSON 函数,然后将结果解析回普通对象。

这两种方法不仅完全有效,而且设计也很好,因为您不应将“跟踪”的 ORM 模型作为 View 模型传递(您在第二个解决方法中正在这样做)。这样做会将您的数据库暴露给不应访问它的应用程序层,并可能导致意外行为。

TLDR: 解决方法 1 是更好的方法

关于node.js - res.render 不加载 Sequelize 数据值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55203532/

相关文章:

javascript - 在socket.io和node.js上使用disconnect函数

javascript - 如何找到 JS_Parse_Error 的来源?

node.js - 从一个 Connect 中间件访问另一个中间件的最佳方式是什么?

sequelize.js - 羽毛 Sequelize 不适用于 `` `原始 : false ``` anymore after upgrading to Buzzard

javascript - 无法找到在 docker 环境中运行的 Node js 应用程序的模块错误

javascript - 如何解码诺克记录的响应

javascript - async.waterfall 不会在最后呈现

node.js - 如何使用sequelize ORM(即多线程)实现集群

javascript - npm install 返回 304 和 404 错误而不是安装包

node.js - 如何使用 express-validator 检查是否存在至少一个参数