Series NodeJS căn bản cho người mới bắt đầu
Ở bài trước, các bạn đã có thể dùng hàm send() để trả về một mã HTML khi client gửi request app.get('/', function(req, res){
res.send("<h2>This is my first app</h2>");
// res.send("Hello World");
})
Bây giờ, ta xét một ví dụ mới như sau: Khi user truy cập vào địa chỉ có dạng: '/users', ta sẽ hiển thị danh sách các users hiện có trên hệ thống ra trình duyệt
Đầu tiên, ta sẽ phải thêm một route đến '/users' để server nhận biết được đường dẫn này
app.get('/users', function(req, res){
// do something here
})
Giả sử chúng ta có 2 users có name và email là {name: user1, email: [email protected]} và {name: user2, email:
[email protected]}. Ta có đoạn code HTML sau để hiển thị 2 user này
<div class="users">
<table>
<thead>
<tr>
<th> Name </th>
<th> Email </th>
</tr>
</thead>
<tbody>
<tr>
<td> User1 </td>
<td> [email protected] </td>
</tr>
<tr>
<td> User2 </td>
<td> [email protected] </td>
</tr>
</tbody>
</table>
</div>
Thêm đoạn code HTML trên vào method send() để server có thể trả về cho client
app.get('/users', function(req, res){
res.send('<div class="users"><table><thead><tr><th> Name </th><th> Email </th></tr></thead><tbody><tr><td> User1 </td><td> [email protected] </td></tr><tr><td> User2 </td><td> [email protected] </td></tr></tbody></table></div>')
})
Và đây là thành quả khi truy cập vào
localhost:8080/users Như vậy, yêu cầu của bài toán được giải đáp. Tuy nhiên, ta có thể thấy, trong hàm send() , ta phải truyền vào toàn bộ code HTML. Nhược điểm của nó, chính là nếu code HTML quá dài, việc làm như thế sẽ làm cho code lẫn lộn giữa JavaScript và HTML. Khi gặp lỗi hay muốn nâng cấp sẽ cực kỳ khó khăn
Do đó, giải pháp được đặt ra, là ta sẽ tạo một file HTML riêng, và render file này Tạo một thư mục views bên trong nodeapp, sau đó, tạo thêm một thư mục users để quản lý các view liên quan đến đối tượng users (việc này sẽ giúp các bạn thuận tiện hơn trong việc quản lý mã nguồn cũng như logic mô hình MVC, mình sẽ nói đến mô hình này sau ).
|--nodeapp
|----views
|------users
Tiếp theo là việc quản lý mã HTML. Trong Express, ta sẽ sử dụng một module là
pug để viết mã HTML.
Tại sao phải dùng pug??? ta vẫn có thể viết HTML bình thường, tuy nhiên, để render file này, ta sẽ dùng phương thức sendFile() trên đối tượng res. Đối số của nó là một đường dẫn tuyệt đối đến file HTML. Đây lại là một nhược điểm cực lớn nữa khi quản lý mã nguồn, sửa lỗi và nâng cấp. Pug là một module giúp ta viết mã HTML một cách cực kì đơn giản. Bạn có thể tham khảo cú pháp ở đây, học sẽ rất nhanh các cú pháp chính Bạn nào chưa quen với cú pháp này, có thể sử dụng Convert HTML to Pug để chuyển mã HTML sang Pug nhé. Giờ ta sẽ sử dụng pug cho project của mình
Cài đặt module pug cho project bằng lệnh: npm install pug --save
Thêm một số cấu hình cho server hiểu về plugin và cây thư mục view của bạn
app.set('views', './views'); // Thư mục views nằm cùng cấp với file app.js
app.set('view engine', 'pug'); // Sử dụng pug làm view engine
Thêm một file có tên là index.pug vào thư mục users, chuyển mã HTML dạng pug vào file này .users
table
thead
tr
th Name
th Email
tbody
tr
td User1
td [email protected]
tr
td User2
td [email protected]
Ta sẽ sử dụng hàm render() thay cho hàm send() . Chi tiết về hàm này các bạn có thể
tham khảo tại: res.render(). Ở đây, mình dùng cú pháp đơn giản nhất, tham số sẽ là đường dẫn tương đối đến file bạn muốn render, tính từ thư mục views
app.get('/users', function(req, res){
res.render('users/index');
})
Restart lại server và truy cập vào localhost:8080/users bạn sẽ thấy kết quả vẫn như dùng hàm send() . Tuy nhiên, code của chúng ta đã gọn,
dễ hiểu, dễ quản lý, sửa chữa, nâng cấp hơn rất nhiều Hãy làm cho web của chúng ta trở nên dynamic hơn một chút. Mình sẽ có một array object lưu thông tin về các user như sau: var users = [{name: "User1", email: "[email protected]"}, {name: "User2", email: "[email protected]"}]
Bây giờ, mình sẽ truyền array này vào hàm render để có thể sử dụng được ở trên view
app.get('/users', function(req, res){
var users = [{name: "User1", email: "[email protected]"}, {name: "User2", email: "[email protected]"}]
res.render('users/index',{users: users});
})
Như vậy, hàm render sẽ nhận thêm 1 tham số nữa. Đây được gọi là các local variable, các biến được khai báo trong tham số này có thể sử dụng ở view. Ở đây mình định nghĩa 1 biến có tên
là users và giá trị của nó là array object users mình khai báo ở trên Tiếp theo, ta điều chỉnh mã HTML một chút. Thay vì viết từng user tĩnh như lúc trước, ta sẽ duyệt qua các phần tử của biến users và in nó ra
.users
table
thead
tr
th Name
th Email
tbody
each user in users
tr
td= user.name
td= user.email
Ta thấy vòng lặp each user in users được sử dụng, đây là cú pháp của pug, các bạn có thể tìm hiểu thêm nhé. Trong pug, để hiển thị một giá
trị, ta sử dụng dấu "=" sau tên thẻ, theo sau đó là giá trị chúng ta muốn hiển thị Xem kết quả nào Kết quả vẫn hiển thị như mong muốn Thông qua bài này, ta đã biết thêm về render HTML trong NodeJS Express, cũng như sử dụng plugin pug để viết mã HTML. Hãy nhớ học về pug để thuận tiện cho các bài học sau nhé... Hẹn gặp lại các bạn!!! |