Nodejs 如何把多个模板render的结果在同一个view上显示?

Nodejs 如何把多个模板render的结果在同一个view上显示?

现在遇到一个问题: 我有用多个http.request从不同的API拿到数据,而数据拿到的时间不是同步的,所以我想每当一个API数据拿完就把对应view render好。可是我用express框架和ejs模板引擎的时候发现模板引擎只能对应render一个view,下一个view被render的时候就会把之前的覆盖。不知道有没有什么好办法把独立的template render完后在同一个view里一个一个显示出来呢?我有想过用jQuery append,但是感觉不是一个特别decent的做法啊?

4 回复

要在Express框架中使用EJS模板引擎将多个异步获取的数据分别渲染到同一个视图中而不互相覆盖,可以通过以下方法实现:

方法概述

  1. 异步获取数据:使用http.request或其他HTTP客户端(如axiosnode-fetch)来异步获取不同API的数据。
  2. 合并数据:在所有数据都获取完成后,将这些数据合并成一个对象。
  3. 渲染视图:一次性将合并后的数据对象传递给视图进行渲染。

示例代码

安装依赖

确保你已经安装了必要的依赖包,例如expressejs等。

npm install express ejs axios

服务器端代码

const express = require('express');
const axios = require('axios');
const app = express();
app.set('view engine', 'ejs');

app.get('/', async (req, res) => {
    try {
        // 异步获取数据
        const [data1, data2] = await Promise.all([
            axios.get('https://api.example.com/data1'),
            axios.get('https://api.example.com/data2')
        ]);

        // 合并数据
        const combinedData = {
            dataFromAPI1: data1.data,
            dataFromAPI2: data2.data
        };

        // 渲染视图
        res.render('index', { data: combinedData });
    } catch (error) {
        console.error(error);
        res.status(500).send('Internal Server Error');
    }
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

EJS 视图模板 (views/index.ejs)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Data Display</title>
</head>
<body>
    <h1>Data from API 1:</h1>
    <pre><%- JSON.stringify(data.dataFromAPI1, null, 2) %></pre>

    <h1>Data from API 2:</h1>
    <pre><%- JSON.stringify(data.dataFromAPI2, null, 2) %></pre>
</body>
</html>

解释

  1. 异步获取数据:使用Promise.all来并行请求两个API,并等待它们全部完成。
  2. 合并数据:将两个API返回的数据合并为一个对象,以便在视图中一起展示。
  3. 渲染视图:一次性将合并后的数据对象传递给EJS模板进行渲染,这样可以避免数据覆盖的问题。

这种方法不仅简洁而且有效,避免了使用JavaScript操作DOM(如append)的复杂性和潜在的性能问题。


第二次rander的时候从req.locals里面取出先前的数据,不可以么

就是说第二次取出第一次的数据然后一起render一下?这样的话和所有数据都取到之后再一起显示是一样的了,感觉这样浪费了很多时间啊,应该取到一组数据就显示一组,这样一组一组asynchronously显示才会更高效不是吗?

在Express框架中使用EJS模板引擎时,可以通过异步操作确保所有API请求完成后再统一渲染页面。可以使用Promise.all来等待所有异步操作(如HTTP请求)完成后,再将结果传递给模板进行渲染。这样可以在同一个视图中展示多个模板的数据。

示例代码

首先,你需要安装必要的库:

npm install express ejs axios

然后,创建一个简单的Express应用来处理多API请求并组合数据:

const express = require('express');
const axios = require('axios');

const app = express();
app.set('view engine', 'ejs');

app.get('/', async (req, res) => {
    try {
        // 创建多个axios实例用于不同API请求
        const [data1, data2] = await Promise.all([
            axios.get('https://api.example.com/data1'),
            axios.get('https://api.example.com/data2')
        ]);

        // 处理数据
        const processedData1 = processData(data1.data);
        const processedData2 = processData(data2.data);

        // 渲染视图并将处理后的数据传递给视图
        res.render('index', { data1: processedData1, data2: processedData2 });
    } catch (error) {
        console.error(error);
        res.status(500).send('An error occurred');
    }
});

// 假设的处理函数
function processData(data) {
    return { ...data, additionalField: 'some value' };
}

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

EJS 模板文件 (views/index.ejs)

在EJS模板文件中,你可以直接访问传递的数据,并根据需要显示它们:

<!DOCTYPE html>
<html>
<head>
    <title>Data from APIs</title>
</head>
<body>
    <h1>Data 1</h1>
    <pre><%- JSON.stringify(data1, null, 2) %></pre>

    <h1>Data 2</h1>
    <pre><%- JSON.stringify(data2, null, 2) %></pre>
</body>
</html>

通过这种方式,你可以确保所有API请求完成后再统一渲染页面,从而在一个视图中展示来自多个API的数据。

回到顶部