在使用 Hapi 框架和 Mongoose 进行开发时,经常会出现虚拟属性无法正确使用的问题。这个问题可能是由于 Hapi 对于 JSON 序列化时的限制,和 Mongoose 默认属性 getters 和 setters 的行为不一致所导致的。
下面将详细介绍这个问题的背景、原因和解决方法,并提供示例代码以供参考。
问题背景
假设我们有一个 User
模型:
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ---------- ------- --------- ------- --- ------------------------------------------- -- - ------ -------------- - - - - -------------- --- ----- ---- - ---------------------- ------------
在 Hapi 中,我们创建一个返回所有用户的路由:
server.route({ method: 'GET', path: '/users', async handler(request, h) { const users = await User.find(); return { users }; } });
但是当我们在浏览器中打开这个路由时,返回的 JSON 中并没有 fullName
属性:
-- -------------------- ---- ------- - -------- - - ------ --------------------------- ------------ ------- ----------- ------ ------ - -- --- - -
问题原因
这是因为 Hapi 在 JSON 序列化时会忽略模型中的 getters 和 setters。而 Mongoose 默认情况下会自动添加 getters 和 setters,因此在 JSON 中无法正确显示虚拟属性 fullName
。
解决方法
方法一:手动转换
一种解决方法是手动将获取的数据转换成非常规 JavaScript 对象,即 toObject()
:
server.route({ method: 'GET', path: '/users', async handler(request, h) { const users = await User.find(); return { users: users.map(u => u.toObject({ getters: true })) }; } });
这种方法可以保证得到包含 fullName
属性的 JSON 响应。
方法二:使用 h.response
另外一种方法是使用 h.response
来手动序列化响应。这种方法可以通过使用 toJSON()
方法来解决虚拟属性无法序列化的问题。
-- -------------------- ---- ------- -------------- ------- ------ ----- --------- ----- ---------------- -- - ----- ----- - ----- ------------ ------ ------------ ----- ---------------------------- - --- --------------------------- --------- -- -- - ----- -------- - ----------------- -- ---------------- -- ------------- --- ---- -- ------------- --- ------------------- - ------ ----------- - --------------- - ------------------------ -------- ---- --- ------ ----------- ---
这种方法通过重写 onPreResponse
生命周期钩子来解决问题。
总结
在 Hapi 框架中使用 Mongoose 时,虚拟属性不能正常序列化的问题可能会经常遇到。本文介绍了两种解决方法,可以帮助开发者迅速修复此类问题。
正确地处理虚拟属性可以提高应用程序的可读性和可维护性,适当的实践和持续学习可以帮助我们更好地开发出健壮的 Web 应用程序。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648f26b848841e9894d7d10b