首页 > 解决方案 > 是否可以创建全局 Ejs 组件?

问题描述

如您所见,我在 index.ejs 文件中包含了我的导航栏组件,并且我对我拥有的每个其他文件都做同样的事情,例如用户页面。有什么方法可以通过将导航栏组件包含在我的所有 ejs 文件中的某个地方一次来使用它吗?而不是将它单独包含在每个 ejs 文件中?

现在我在我的每个文件中都这样做:

索引.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>

标签: javascriptejs

解决方案


正如您在评论中要求的那样,这是我的方法:
我在项目中有“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>

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


推荐阅读