【问题标题】:Persist data sent to a Pug template via render持久化通过渲染发送到 Pug 模板的数据
【发布时间】:2021-12-01 10:31:39
【问题描述】:

我正在尝试找出如何将我从 Express 渲染方法传递给我的 Pug 模板的数据持久化。

我将一些 JSON 数据传递给 Express 中的 res.render() 方法,该方法使用 Pug 呈现我的视图。在 Pug 模板上,我立即使用该数据用 JSON 数据中的下拉值填充我的选择元素之一。

然后我想做的是存储这些传递的数据,以便我可以在为另一个字段创建的事件处理函数中使用它。

基本上,我传递的是表名和表的字段名,但对于 JSON 数据中的每个表。

所以形状就像[{ tableName: "table name here", fieldNames: ['field1', 'field2', ...] }, ... ]

我有一个“选择表名”的选择字段,当用户选择一个表名时,我想获取第二个选择字段的 fieldNames,允许他们选择要使用的字段名。所以我在“选择表名”字段上有一个事件处理程序设置,它运行我在 pug 模板中设置的一个小事件处理程序。唯一的问题是事件处理程序无法访问最初传递给 Pug 模板的数据。

我正在尝试用谷歌搜索,但没有找到任何东西,所以有谁知道我如何在 pug 模板中保存通过 res.render() 方法发送的数据,以便在页面在事件处理程序中呈现后使用或其他功能?

谢谢!

【问题讨论】:

    标签: node.js express model-view-controller pug


    【解决方案1】:

    始终清楚在服务器 (pug) 上做了什么,在客户端 Javascript (浏览器) 上做了什么。

    虽然传递给 pug 脚本的数据是在服务器上使用的,但为了更好的说法,可以将服务器数据注入客户端 Javascript 变量

    以下使用 Express 传递的完全相同的数据在同一页面上创建两个下拉列表。一种是在服务器端生成的,另一种是完全由在浏览器中运行的 Javascript 创建的。

    快递代码:

    app.get("/testdata", (req, res) => {
      res.render("testdata", { data: [ 1, 2, 3, 4, 5]});
    });
    

    testdata.pug:

    html
      head
      body 
        p Dropdown list generated at the server:
        p 
          select  
            each n in data 
              option(value=n)=n
              br
    
        p Dropdown list generated in browser Javascript: 
        p 
          select#dropdown
    
      script.
        document.body.onload = () => {
          const dropdown = document.getElementById("dropdown");
          let data = JSON.parse(`!{JSON.stringify(data)}`); // line 18
          data.forEach(d => {
            const item = document.createElement("option");
            item.innerText = d;
            dropdown.appendChild(item);
          })
        }
    

    我在指向不同实体的完全不同的上下文中使用了相同的变量名。小心不要绊倒。例如,看第 18 行:

       let data = JSON.parse(`!{JSON.stringify(data)}`); // line 18
    
    1. data 的第一个实例是 浏览器 中的 Javascript 变量。
    2. data 的第二个实例是一个 server 对象,通过render 方法传递给 pug 脚本。基本上,在 pug 文件中找到的任何 !{expression} 实例都会在呈现视图时进行评估¹。

    ¹ 我认为表达式已被评估并调用其 toString 方法。如果我知道它是一个数组,我可以使用:

      let data = [!{data}]; // line 18
    

    【讨论】:

    • 谢谢老鬼!我自己设法弄明白了,但我几乎使用了与您在此处使用的方法相同的方法,只是对用于创建选项元素的方法略有不同。主要的事情似乎是将它包装在 #{} 中并在其上使用 JSON.stringify() 方法来解析它。
    • 是的,将对象字符串化更安全,因此如果您只是将其“粘贴”到字符串变量中,就不会出现引号“之类的错误。
    猜你喜欢
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多