是否可以创建全局Ejs组件?

问题描述 投票:0回答:1

您可以看到,我的navbar组件包含在index.ejs文件中,而我拥有的所有其他文件都在做同样的事情,例如用户页面。有什么办法可以通过将我的navbar组件包含在某个地方一次而在所有ejs文件中使用它?而不是将其分别包含在每个ejs文件中?

目前,我正在每个文件中都这样做:

index.ejs:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <% include components/navbar %>

        rest of the code...

    </body>
</html>
javascript ejs
1个回答
1
投票

根据您在评论中的要求,这是我的方法:我在项目中有“ views”文件夹,其中包括以下文件夹:

  • 资产
  • 布局

以及它们旁边的动态ejs文件假设我们要渲染此布局,该布局在每个页面中都有一个页眉,但正文不同:

布局:

  <html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <% for (let cssLink of cssLinks) { %>
    <link rel="stylesheet" href="<%= cssLink  %>" />
    <% } %>
    <title>home page</title>
  </head>
  <body>
    <h1>THIS IS HEADER!</h1>

    <div id="demo">
      <%- mainView %>
    </div>
  </body>
</html>

您可以看到主体中有一个变量mainView,所以让我们看看如何在其中插入动态主体:我的实用程序文件夹中有一个函数,可以减少代码的重复:

const ejs = require('ejs');
const path = require('path');
const layoutsPath = path.join(__dirname, "./../views/layouts/");
const assetsPath = path.join(__dirname, "./../views/assets/");
const viewsPath = path.join(__dirname, './../views/');
const load = (basePath, filename, data, cb = null) => {
    let route ;
    switch (basePath) {
        case 'layout': {
             route = layoutsPath;
             break;
        }
        case 'asset': {
             route = assetsPath;
             break;
        }
        case 'view': {
             route = viewsPath;
             break;
        }
        default: {
             route = basePath;
        }
    }

    ejs.renderFile(path.join(route, filename), data, (err, str) => {
        if (err) {
            console.log(err);
            return err;
        }
        if (cb === null) {
            return str;
        } else {
            return cb(str);
        }

    });
}

module.exports = {
    load
}

现在在index.js中,我想将home.ejs中的header.ejs输出到客户端:

let allUsers = await usersModule.findAll();
let renderedHTML = '';
load('view', 'home.ejs', { allUsers }, (rendered) => {
    load('layout', 'header.ejs', { mainView: rendered, cssLinks: ['/css/header.css'] }, (fullView) => {
        renderedHTML = fullView;
    });
});
res.status(200).send(renderedHTML);

所以我在这里从数据库中获取我的身体所需的数据,并将其传递到home.ejs,在那里我循环并渲染我的身体视图,例如home.ejs:

    <div>
  <% for (let user of allUsers) { %> 

        <ul>
            <li>email : <%= user.email %></li>
            <li>name : <%= user.name %></li>
        </ul>

    <% } %>
</div>

rendered body作为参数传递给我们的回调,我们现在可以使用变量名mainView将其传递给标头,因此在标头中,整个呈现的主体将插入到布局的正确位置。现在我们的布局和动态主体已经合并,可以发送给客户端了

© www.soinside.com 2019 - 2024. All rights reserved.