通过NodeJS获取JSON数据时,如何通过ExpressJS更新我的EJS模板?

时间:2016-12-21 22:11:15

标签: javascript json node.js express ejs

我使用NodeJS调用一些API,并使用以下代码通过ExpressJS将它们传递给我的EJS模板:

app.get('/', function (req, res) {
res.render('routes/index', {
    plLoopTimes: plLoopTimes,
    pl54Times: pl54Times
})
});

在这种情况下,plLoopTimespl54Times是由我从API获取的JSON填充的数组。在我的EJS模板中,我可以通过在两个阵列上运行forEach来获取数据。我面临的问题是,当我第一次启动节点服务器时,我从API获取新数据,并且新数据被提供给EJS模板,但我想每分钟轮询API并获得新鲜数据。现在,我在服务器端脚本上使用setInterval()每分钟调用一次API,但我无法弄清楚如何在不刷新整个页面的情况下将新数据传递到EJS模板中,我不知道我想做。我试图创建一个客户端脚本来更改我想要显示数据的元素的innerHTML,但是如果我在脚本文件中输入EJS语法并将其传递给innerHTML,那么EJS模板不表达该语法,而是我的脚本只将EJS字符串输出到页面中。那么,有没有人对如何将服务器端代码中的变量更新到客户端的EJS模板有任何建议?

2 个答案:

答案 0 :(得分:2)

我认为你做错了。如果您需要实时行为,只需使用正确的工具即可。对于这种需要,我会使用SocketIO。如果你需要旧的浏览器支持,你也可以通过简单的ajax来实现,但是web套接字优于ajax的好处很大。

Socket.io

这是一个简单的SocketIO服务器,每1分钟向所有客户端发送数据。

import socketio from 'socket.io';
import { DataRepository } from 'repositories';


const server = http.createServer();
const io = socketio(server);

io.on('connection', (client) => {
  ((interval = 60000, io) => {
    setInterval(() => {
      const data = DataRepository.fetch();
      client.emit('new', data);
    }, interval);
  })();
});

所有客户只需创建SocketIO实例并收听new

const socket = io('http://yoursite.com:port');
socket.on('emit', data => {
  updateView(data);
});

function updateView ({ plLoopTimes, pl54Times}) {
  plLoopTimes.forEach(t => {
    // update things
  });
  pl54Times.forEach(t => {
    // update things
  });
}

后备

另一种方法 - 更经典 - 是在客户端而不是服务器上定义间隔。因此,每次客户端请求新版本的视图时,服务器将视图呈现为字符串并发送回客户端。

这里我们只需要定义一个指向视图的简单路径:

router
  .get('/looptimes', (req, res) => {
    const { plLoopTimes, pl54Times } = DataRepository.fetch();
    // render the file 'looptimes.ejs' to string
    const view = ejs.render('looptimes', {
      plLoopTimes, pl54Times
    });
    res.type('.html');
    res.send(view);
  });

在前端,您只需要更新HTML。

答案 1 :(得分:0)

你已经掌握了大部分权利,假设你没有遇到竞争条件,当你收到页面请求时json实际上没有准备就绪。要在模板中访问plLoopTimes和pl54Times,如果你将它们传递给res.render()就像你需要做的那样:

<%= pl54Times.some.property %>

或者如果你想循环json中的一系列项目,你可以这样做:

<% for(var i=0; i < arrayName.length; i++) { %>
    <div><%= arrayName[i].some.property.to.display %></div>
<% } %>

希望这有帮助!