Ở bài trước mình đã hướng dẫn các bạn về cách cài đặt cũng như khai báo những cái view, các kế thừa để giảm bớt code trùng lặp của menu, header, footer, style, scrypt, …

Link bài viết trước ở đây

Truyền dữ liệu trên view

Phần lớn nội dung website đều được xử lý ở server và trả về cho phía client, và cách truyền dữ liệu qua view mình sẽ hướng dẫn ngay bên dưới.

Mở lại source code ở bài trước, cập nhật lại một xíu file index.js.

...
app.get('/', (req, res) => {
    res.render('index', {
        name: 'Quang Dat',
        age: 23
    });
})
...

Tiếp tục chỉnh sửa file views/index.js để hiển thị dữ liệu được truyền qua:

<h1>Hello <%= name %> - <%= age %></h1>

Đừng quên chạy node index, sau đó truy cập http://localhost:3000

Truyền dữ liệu qua partials

Quay trở lại 1 xíu, mình sẽ trình bày cái ý tưởng chỗ này.
Theo source code của bài hôm trước, chúng ta có file master.ejs include file header.ejs. Giả sử trong file trong thằng header này, ta muốn hiển thị một cái data gì đó, ở đây mình sẽ hiển thị một cái menu. Và cái menu này là một cái menu động, nghĩa là ta sẽ truyền dữ liệu và hiển thị ra.

Tiếp tục cập nhật file index.js

...

app.get('/test', function(req, res) {
    res.render('index', {
        name: 'Quang Dat',
        age: 23,
        menu: [
            {
                label: 'home',
                link: '/'
            },
            {
                label: 'datnq',
                link: 'https://nqdat.com'
            }
        ]
    });
});
    
...

Cập nhật lại file master.ejs để truyền dữ liệu menu qua

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>master</title>
</head>
<body>

    <%- include('./partials/header.ejs', { transMenu: menu }) %>

    <%- body %>
    <%- include('./partials/footer.ejs') %>
</body>
</html>

Mở file menu header.ejs và hiển thị menu thông qua biến transMenu

<header>Header</header>
<nav>
    <ul>
        <% transMenu.forEach((item) => { %>
            <li>
                <a href="<%= item.link %>"><%= item.label %></a>
            </li>
        <% }) %>
    </ul>
</nav>

Lưu ý
Trong file header.ejs ta hoàn toàn có thể sử dụng biến *menu, vì đây là ví dụ nên mình truyền gì dùng đó, nhiều trường hợp ta chỉ truyền 1 phần tử trong mảng menu chẳng hạn.

Các bạn nhìn vào hàm forEach các bạn có thể hình dùng cách chúng ta dùng các tag trong EJS engine.

Thử làm việc với If else nhá, ta chỉnh sửa lại file header.ejs một xíu

<header>Header</header>
<nav>
    <ul>
        <% transMenu.forEach((item) => { %>
            <% if (item.link == '/') { %>
            <li>
                <a href="<%= item.link %>"><%= item.label %></a>
            </li>
            <% } %>
        <% }) %>
    </ul>
</nav>

ở đây chúng ta chỉ hiển thị nếu đường dẫn là “/“ và tất nhiên nó chỉ hiển thị home

Chúng ta cũng có những logic khác như for, while, … khai báo tương tự như những ví dụ trên.

Xử lý menu

Quay trở lại 1 xíu, có phải chúng ta đang truyền menu từ hàm xử lý ( sau này khi tách ra gọi là Controller) truyền đến file index.ejs, file này đang sử dụng layout master.ejs và hiển thị nó ra. Nhưng các bạn biết đó, 1 website đâu phải chỉ có 1 trang index, và tất nhiên chung ta đâu chỉ hiển thị menu tại trang index.
Như vậy, ta đâu thể nào truyền biến menu ở tất cả các route, vì vậy ta cần phải thay đổi chỗ này 1 xíu.

Có nhiều cách để có thể xử lý chỗ này, ở đây mình sữ dụng middleware để auto truyền biến menu đến view

Mở file index.js và cập nhật một xíu

...

app.use((req, res, next) => {
    res.locals.menu = [
        {
            label: 'home',
            link: '/'
        },
        {
            label: 'datnq',
            link: 'https://nqdat.com'
        }
    ];
    next();
});

...

app.get('/test', function(req, res) {
    res.render('index', {
        name: 'Quang Dat',
        age: 23,
    });
});

...

Lưu ý: Các bạn phải khai báo bên trên các Route.
Các bạn thử tạo những Route khác kiểm tra thử có như mình nói không nha.

Kết luận

Mình vừa chia sẻ một số kiến thức khi làm việc với view.

Nguồn tham khảo:

Rất mong được sự ủng hộ của mọi người để mình có động lực ra những bài viết tiếp theo.
{\__/}
( ~.~ )
/ > ♥️ I LOVE YOU 3000

JUST DO IT!