View là một thành phần trong mô hình MVC. Tuy mô hình này càng ngày càng ít được sử dụng hơn lúc trước vì có nhiều framework hay thư viện hỗ trợ phía front end. Nhưng nó không đồng nghĩa với việc mô hình này không được sử dụng nhiều.
Cùng mình tìm hiểu về view trong NodeJs, coi nó hoạt động như thế nào nhá!

Cài đặt

Phần setup mình không hướng dẫn lại nữa nhé, các bạn có thể coi lại những phần trước.

Cấu trúc folder và các file của bài sẽ có dạng:

views
    partials
        footer.ejs
        header.ejs
    index.ejs
    master.ejs
    master1.ejs
index.js
package.json
...

Mình tiến hành cài đặt các package cho bài hôm nay.
Có rất nhiều view engine trong NodeJs, nhưng ban đầu mình tiếp xúc với NodeJs thì mình học về EJS View Engine và chúng ta cũng không cần thông thạo nhiều view engine để làm gì cả, chỉ cần làm việc với 1 cái trơn tru là được ròi.

npm install express ejs express-ejs-layouts

Mở file index.js và bắt tay setup server:

const express = require('express');
const app = express();
const expressLayouts = require('express-ejs-layouts');

app.use(expressLayouts);

app.set('view engine', 'ejs')
app.set('views', 'views');
app.set('layout', './master');

app.get('/', (req, res) => {
    res.render('index');
})

app.listen(3000, function() {
    console.log('Server running: http://localhost:3000');
});

Code EJS

EJS view engine là một template, và được sử dụng để tạo ra các đánh dấu HTML. Nói nôm na là code như HTML luôn ý, nhưng nó hỗ trợ thêm các syntax để có thể làm việc với dữ liệu.

Ở đây mình làm đơn giản cho các bạn hiểu, không đánh mạnh vào code css hay html.

Lần lượt chỉnh sửa các file EJS chúng ta đã tạo theo cấu trúc bên trên.

Sau khi update code mình sẽ giải thích một xíu về ý tưởng này.

footer.ejs

<footer>
    Footer
</footer>

header.ejs

<header>
    Header
</header>

index.ejs

<h1>Hello world!</h1>

master.ejs

<!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') %>
    <%- body %>
    <%- include('./partials/footer.ejs') %>
</body>
</html>

master2.ejs

<!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 2</title>
</head>
<body>
    <%- include('./partials/header.ejs') %>
    <%- body %>
    <%- include('./partials/footer.ejs') %>
</body>
</html>

Mở Terminal hay CMD tại folder ứng dụng, chạy command:

node index

Tới đây là đã thành công việc tạo view và kế thừa view.

Giải thích

Bây giờ mình sẽ giải thích một xíu về lý do cũng như ý tưởng vì sao lại code như vậy.

Đầu tiên là các file trong folder partials là nơi lưu giữ các thành phần của website chúng ta. Các bạn có thể đặt tên gì cũng được, hoặc có thể để trực tiếp trong folder views luôn. Và tên các folder cũng như file chúng ta có thể đặt tên tùy thích. Nhưng tốt nhất nên đặt theo một cái chuẩn gì đó hoặc phù hợp với chức năng của nó để dễ dàng làm việc hơn.

Ở đây các thành phần như header, head, footer, script, menu, … các block v.V… và được gọi lại nhiều lần ở các trang. Chúng ta chỉ cần vào đây chỉnh sửa. Nếu muốn bỏ đi thì đơn giản không gọi nó trong file index.ejs(page) hoặc file master.ejs(layout).

Một website luôn có những thành phần cố định không thay đổi như header, footer, các đoạn mã style hay thư viện css, mã script hay thư viện js,… Từ đó chúng ta sinh ra file master.ejs.

Để kế thừa được file này, ta phải sử dụng package express-ejs-layouts để có thể hoạt động. Trong file master này, ta khai báo <%- body %> để nó có thể nhận biết nơi mà nó sẽ chèn code của file view (index.ejs) vào tại vị trí đó. Chúng ta vẫn có thể khai báo nhiều nơi để hiển thị những giá trị khác ra, và ta phải truyền giá trị đó vào nhé. Body là biến đặc biệt của thư viện rồi.

Lưu ý
Ở trên mình có tạo ra file master2.ejs và vẫn chưa sử dụng tới, không tự nhiên mà mình tạo ra nó đâu các bạn. Mình sẽ giải thích một số trường hợp khác để sử dụng đến nó á:

Một website bình thường thì chỉ có phần giao diện của người dùng, nên thành ra chúng ta chỉ cần 1 file master.ejs thôi. Nhưng website khác có phần quản lý admin nữa thì sao, chúng ta phải sử dụng giao diện khác, thì chúng ta phải có một file master.ejs khác. Ở đây mình dùng master2.ejs. Chúng ta đã khai báo app.set('layout', './master'); nên mặc định nó sẽ lấy file master.ejs thành ra mình phải Override cái thằng layout này bằng cách mình sẽ truyền thằng layout thành master2.ejs khi render file view.

app.get('/', (req, res) => {
    res.render('index', {layout: './master2'});
})

Reload lại trang ta thấy title đã trở thành master 2 nghĩa là đó đang kế thừa thằng master2.ejs.

Thêm một tường hợp nữa: Giả sử chúng ta không muốn kế thừa bất kì thằng layout nào luôn thì sao? Đơn giản ta làm như sau:

app.get('/', (req, res) => {
    res.render('index', {layout: false});
})

Nếu truyền null thì mặc định nó vẫn lấy thằng layout mà chúng ta đã set bên trên nhá.

Các tags trong EJS

  • <% thẻ ‘Scriptlet’, sử dụng cho control-flow (if, for, …), không có output
  • <%_ loại bỏ các khoảng trắng trước nó
  • <%= xuất giá trị vào và kết thúc
  • <%- xuất giá trị và không kết thúc
  • <%# thẻ comment, không thực thi, không có output
  • <%% xuất ra ‘<%’
  • %%> xuất ra ‘%>’
  • %> thẻ kết thúc thông thường
  • -%> xóa dòng mới ở cuối
  • _%> xóa tất cả khoảng trắng sau nó

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.
Ở bài sau mình sẽ hướng dẫn các bạn làm việc với data trên 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!