在客户端 JavaScript 中访问 Express.js 局部变量

IT技术 javascript node.js express pug
2021-02-12 06:39:24

很好奇我是否做对了,如果不是,你们会如何处理这个问题。

我有一个 Jade 模板,需要呈现从 MongoDB 数据库中检索到的一些数据,我还需要访问客户端 JavaScript 文件中的这些数据。

我正在使用 Express.js 并将数据发送到 Jade 模板,如下所示:

var myMongoDbObject = {name : 'stephen'};
res.render('home', { locals: { data : myMongoDbObject } });

然后在home.jade 中,我可以执行以下操作:

p Hello #{data.name}!

其中写出:

Hello stephen!

现在我想要的是还可以访问客户端 JS 文件中的这个数据对象,这样我就可以在将对象发布回服务器以更新数据库之前,在单击按钮时操作对象。

我已经能够通过将“数据”对象保存在 Jade 模板的隐藏输入字段中,然后在我的客户端 JS 文件中获取该字段的值来实现这一点。

内宅.jade

- local_data = JSON.stringify(data) // data coming in from Express.js
input(type='hidden', value=local_data)#myLocalDataObj

然后在我的客户端 JS 文件中,我可以像这样访问 local_data:

在 myLocalFile.js 中

var localObj = JSON.parse($("#myLocalDataObj").val());
console.log(localObj.name);

然而,这种字符串化/解析业务感觉很混乱。我知道我可以将我的数据对象的值绑定到我的 Jade 模板中的 DOM 对象,然后使用 jQuery 获取这些值,但我想在我的客户端 JS 中访问从 Express 返回的实际对象。

我的解决方案是否最优,你们将如何实现?

5个回答

渲染完成后,仅将渲染的 HTML 发送到客户端。因此,将不再有变量可用。您可以做的是,不是在输入元素中写入对象,而是将对象输出为呈现的 JavaScript:

script(type='text/javascript').
    var local_data =!{JSON.stringify(data)}

编辑:显然 Jade 在第一个右括号后需要一个点。

建议的解决方案有效,我还推荐express-expose以更干净和集成的方式来公开服务器端变量。
2021-03-19 06:39:24
我仍然看到“数据”在脚本标签内未定义。
2021-03-31 06:39:24
好的,这比我的输入字段解决方案要好,因为它不需要将 JSON 字符串解析回对象或使用 jQuery 查找输入字段的值。
2021-04-04 06:39:24
这对我不起作用,我得到 [object Object]。我可能在服务器端用 stringify 或 parse 做错了什么吗?
2021-04-13 06:39:24
@Costa 根据您的视图引擎,您可能无法从视图中调用 JSON.stringify。相反,您应该在控制器中对其进行字符串化并将字符串作为变量传递,例如{{{jsonData}}}(在车把的情况下)。
2021-04-13 06:39:24

我做的有点不同。在我的控制器中,我这样做:

res.render('search-directory', {
  title: 'My Title',
  place_urls: JSON.stringify(placeUrls),
});

然后在我的玉文件中的 javascript 中,我像这样使用它:

var placeUrls = !{place_urls};

在这个例子中,它用于 twitter bootstrap typeahead 插件。如果需要,您可以使用这样的方法来解析它:

jQuery.parseJSON( placeUrls );

另请注意,您可以省略本地人:{}。

考虑当地人是什么意思@braitsch
2021-03-22 06:39:24
+1 关于忽略当地人的说明,我不知道你能做到这一点。
2021-03-27 06:39:24
@iamrudra 没有必要在渲染函数中的 locals 对象前加上“locals”这个词。res.render('home', { { data : myObject } })很好,res.render('home', { locals : { data : myObject } })尽管为了清楚起见,我可能会建议您无论如何都这样做。
2021-03-31 06:39:24
@braitsch:这对我来说是新鲜事。我在学校做过 node 和 express 项目,但从未使用过 locals 对象。你能指点我正确的文档/阅读材料吗?
2021-04-04 06:39:24

使用 Jade 模板:

如果您在包含的静态 HTML 文件上方插入 @Amberlamps 代码片段,请记住指定!!! 5在顶部,以避免您的样式被破坏,在views/index.jade 中

!!! 5
script(type='text/javascript')
    var local_data =!{JSON.stringify(data)}

include ../www/index.html

这将在实际静态 HTML 页面加载之前传入您的 local_data 变量,以便该变量从一开始就全局可用。

服务器端(使用 Jade 模板引擎)- server.js

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');

app.get('/', ensureAuthenticated, function(request, response){
    response.render('index', { data: {currentUser: request.user.id} });
});

app.use(express.static(__dirname + '/www'));

您不需要在渲染调用中传递局部变量,局部变量是全局变量。在您的 pug 文件调用中,不要放置键表达式,例如#{}. 只需使用类似的东西: base(href=base.url)

这里base.urlapp.locals.base = { url:'/' };

你听说过 socket.io 吗?(http://socket.io/)。从 express 访问对象的一种简单方法是在 node.js 和您的 javascript 之间打开一个套接字。通过这种方式,数据可以轻松传递到客户端,然后使用 javascript 轻松操作。代码不必太多,只需一个socket.emit()来自 node.js 和一个socket.on()来自客户端。我认为这将是一个有效的解决方案!

这是用锤子打蜜蜂。它几乎没有增加很多请求。
2021-03-23 06:39:24
确切地说,在这种情况下,Socket.io 是矫枉过正。我正在寻找将 JS 变量从服务器传输到客户端脚本的最简单的方法。
2021-03-25 06:39:24
大声笑,我有点喜欢亚历克斯的建议,砰!啊所有那些讨厌的当地人 bam bam!
2021-03-27 06:39:24