解决了! 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”,因为它不是其父级的“自己的属性”

已拒绝访问以解析属性“大小”,因为它不是其父级的“自己的属性”

为啥 user.username 在车把中不起作用

使用带有节点和快递的把手#each 时出错

请问如何添加运行时选项来禁用检查或此警告