解决了! Handlebars:访问已被拒绝解析属性“名称”,因为它不是其父级的“自己的属性”已修复
Posted
技术标签:
【中文标题】解决了! Handlebars:访问已被拒绝解析属性“名称”,因为它不是其父级的“自己的属性”已修复【英文标题】:Solved! Handlebars: Access has been denied to resolve the property "name" because it is not an "own property" of its parent Fixed 【发布时间】:2021-04-25 13:43:19 【问题描述】:我正在尝试获取用户在表单字段中输入的详细信息,以便我可以编辑和更新所选记录。但是,当我单击编辑按钮时,我会在表单中看到空白的表单字段。
router.get('/list', (req, res) =>
Employee.find((err, docs) =>
if (!err)
res.render("employee/list",
list: docs,
);
else
console.log('Error in retrieving employee list :' + err);
);
)
我不知道出了什么问题。我已将用户输入的值传递为req.body
。所有操作均正常运行,但无法更新记录,因为我无法从表单中获取用户 ID。
<tbody>
#each list
<tr>
<td>this.name</td>
<td>this.email</td>
<td>this.mobile</td>
<td>this.city</td>
<td>
<a href="/employee/this._id"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a>
<a href="/employee/delete/this._id" onclick="return confirm('Are you sure to delete this record ?');"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a>
</td>
</tr>
/each
</tbody>
【问题讨论】:
【参考方案1】:如果您使用的是猫鼬和较新版本的 express-handlebars,则可以通过在 find() 之后使用 lean() 方法来解决,例如:
router.get('/list', (req, res) =>
Employee.find((err, docs) =>
if (!err)
res.render("employee/list",
list: docs,
);
else
console.log('Error in retrieving employee list :' + err);
)**.lean()**; // It is prevent the warning when trying to display records
)
---------------- 您可以遵循的另一个选项 ----------------------- -----
express-handlebars 不允许您指定运行时选项以传递给模板函数。此软件包可帮助您禁用模型的原型检查。
步骤:
1 - 安装依赖项
npm i @handlebars/allow-prototype-access
2 - 以这个 sn-p 为例来重写你的 express 服务器
const express = require('express')
const path = require('path')
**const Handlebars = require('handlebars')**
**const hbs = require('express-handlebars');**
const bodyParser = require('body-parser');
**const allowInsecurePrototypeAccess = require('@handlebars/allow-prototype-access');**
const employeeController = require('./controller/employeeController')
const app = express()
app.use(bodyParser.urlencoded( extended: true ))
app.use(bodyParser.json())
app.set('views', path.join(__dirname, '/views/'))
app.engine('hbs', hbs( extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/', **handlebars: allowInsecurePrototypeAccess(Handlebars)** ))
app.set('view engine', 'hbs')
app.listen(3000, () =>
console.log('Server started at port 3000')
)
app.use(employeeController)
3 - 运行服务器并跳起快乐的舞蹈。
【讨论】:
【参考方案2】:如果你使用 mysql,sequelize,使用原始查询选项raw: true
,如果你使用关系,你可以使用nest: true
,例如:
users = await User.findAll(
where: username: "SimonAngatia" ,
include: [ model: Tweet, as: "Tweets" ],
raw: true,
nest: true,
).catch(errorHandler);
参考这里:Sequelize, convert entity to plain object
【讨论】:
但是请注意,raw: true, nest: true
在一对多关系(您希望数组出现在输出中)的情况下不会按预期工作。而不是数组,您只会得到第一个结果作为对象。最好的解决方法是调用result.toJSON()
- 请注意,这将不返回一个实际的 JSON 字符串,而只是一个 Sequelize 认为适合 JSON 字符串化的简化对象。这正是我们想要的 Handlebars。
所以在原始问题中,将list: docs
替换为list: docs.toJSON()
应该可以。【参考方案3】:
您可以在数据传输之前自定义文档。
router.get('/list', (req, res) =>
Employee.find((err, docs) =>
if (!err)
docs= docs.map(item=> item.toObject())
res.render("employee/list",
list: docs,
);
else
console.log('Error in retrieving employee list :' + err);
);
)
【讨论】:
以上是关于解决了! Handlebars:访问已被拒绝解析属性“名称”,因为它不是其父级的“自己的属性”已修复的主要内容,如果未能解决你的问题,请参考以下文章
Handlebars:访问已被拒绝解析属性“imagePath”,因为它不是其父级的“自己的属性”
Handlebars:访问已被拒绝解析属性“some prop”,因为它不是其父级的“自己的属性”