{"name":"nodejs","version":"1.0.0","main":"app.js","scripts": {"test":"echo \"Error: no test specified\" && exit 1" },"keywords": [],"author":"","license":"ISC","description":"","dependencies": {"express":"^4.21.1","pug":"^3.0.3" }}
views\users\index.pug
h2 Searchingform.seach-form(action="/users/search")input(name="name", type="text", placeholder="name")input(name="age", type="text", placeholder="age")input(type="submit").usersh2 All usersifusers.length>0tabletheadtrth Name th Action tbodyeach user in userstrtd= user.name tda(href="/users/"+user.id) Viewelsep No user to displaya(href="/users/create") Create new user
h2 Show userpspan User name: span= user.namepspan User email:span= user.emailpspan User age:span= user.age
app.js
constexpress=require('express'); // Require module express vào projectconstapp=express(); // Tạo một app mớiconstport=8000; // Định nghĩa cổng để chạy ứng dụng NodeJS của bạn trên server// Require user routeconstuserRoute=require('./routes/user')app.set('views','./views'); // Thư mục views nằm cùng cấp với file app.jsapp.set('view engine','pug'); // Sử dụng pug làm view engineapp.use(express.json()) // for parsing application/jsonapp.use(express.urlencoded({ extended:true })) // for parsing application/x-www-form-urlencoded// Dùng userRoute cho tất cả các route bắt đầu bằng '/users'app.use('/users', userRoute);app.get('/',function(req, res){res.send("<h2>This is my first app</h2>");})app.listen(port,function(){console.log('Your app running on port '+ port);})
controllers\user.js
var users = [ { id:1, name:"User1", email:"user1@gmail.com", age:31 }, { id:2, name:"User2", email:"user2@gmail.com", age:20 }, { id:3, name:"User1", email:"user1.2@gmail.com", age:25 },];module.exports= {index:function (req, res) {res.render("users/index", { users: users, }); },search:function (req, res) {var name_search =req.query.name; // lấy giá trị của key name trong query parameters gửi lênvar age_search =req.query.age; // lấy giá trị của key age trong query parameters gửi lênvar result =users.filter((user) => {// tìm kiếm chuỗi name_search trong user name.// Lưu ý: Chuyển tên về cùng in thường hoặc cùng in hoa để không phân biệt hoa, thường khi tìm kiếmreturn (user.name.toLowerCase().indexOf(name_search.toLowerCase()) !==-1&&user.age ===parseInt(age_search) ); });res.render("users/index", { users: result,// render lại trang users/index với biến users bây giờ chỉ bao gồm các kết quả phù hợp }); },get_create:function (req, res) {res.render("users/create"); },post_create:function (req, res) {users.push(req.body);res.redirect("/users"); },show:function (req, res) {var user =users.find((user) => {returnuser.id ==parseInt(req.params.id); });res.render("users/show", { user: user, }); },};
routes\user.js
constexpress=require('express');constuser_router=express.Router();// Require user controllerconstuser_controller=require('../controllers/user');user_router.get('/',user_controller.index) // Lấy hàm ở key indexuser_router.get('/search',user_controller.search)user_router.get('/create',user_controller.get_create)user_router.post('/create',user_controller.post_create)user_router.get('/:id',user_controller.show)// Exports cho biến user_routermodule.exports= user_router;
Như đã nói, trong bài số 8 này, chúng ta sẽ tìm hiểu về controller, thành phần tiếp theo của mô hình MVC
Trong các bài trước, ta có thể phân chia việc xử lý trong các file route thành 2 phần
Phần 1: Định nghĩa route cho 1 request
Phần 2: Viết các câu lệnh xử lý cho route đó
Tuy nhiên, trong thực tế, chúng ta sẽ không làm vậy. Đối với file route chúng ta chỉ thực hiện Phần 1. Còn đối với Phần 2, chúng ta sẽ tách riêng thành các file khác, gọi là controller. Sau đó sẽ liên kết 2 phần này lại với nhau
Việc làm này sẽ giúp chúng ta tuân thủ mô hình MVC. Rõ ràng, đoạn mã xử lý được tách riêng sẽ giúp chúng ta dễ dàng quản lý, nâng cấp hơn, tính tái sử dụng cũng sẽ cao hơn. Bắt tay vào làm ngay nhé:
Tạo một folder mới có tên là controllers trong thư mục nodeapp . Đây sẽ là thư mục chứa các file controller của chúng ta
|--nodeapp
|----controllers
Tiếp theo, tạo một file user.js để xử lý các công việc liên quan đến đối tượng user
// handle user
Ở bài trước, ta đã có đoạn routes trang index của users như sau
Ở đây, ta sử dụng module.exports để xuất nội dung, cái này mình đã nói ở các bài trước. Lần này, nội dung của nó là 1 JavaScript Object, là tập hợp các cặp key:value. Cái này các bạn đã được học ở JavaScript
Trong đoạn code trên, bạn có thể thấy mình định nghĩa key chính là index, còn value của nó là hàm mà mình tác từ user_routes
Ồ, nhưng biến users trong đoạn mã trên từ đâu ra nhỉ. À, nó chính là mảng các users ở file routes, ta sẽ chuyển nó qua luôn nhé
Tiếp theo, ta sẽ liên kết giữa controller và route thông qua phương thức require
// Require user controllerconstuser_controller=require('../controllers/user');
Như vậy, biến user_controller bây giờ chính là object mà ta đã export ở file controller/user.js. Do đó, ta sẽ sửa phần route trang index của users thành như sau:
user_router.get('/',user_controller.index) // Lấy hàm ở key index
OK!!! Bây giờ hãy thử khởi động là app.js, và truy cập lại vào http://localhost:8080/users/ để xem kết quả. Mọi thử vẫn diễn ra bình thường, như vậy, ta đã làm đúng
Cuối cùng, bạn hãy tiếp tục thực hiện tách các đoạn xử lý của user route qua controller cho các route còn lại nhé!!! Bài tập thực hành cho bạn đấy (Lời giải mình sẽ để ở dưới, nhưng hãy tự làm trước khi xem lời giải nha)
Sau khi thực hiện bài tập trên, ta sẽ có kết quả của 2 file như sau:
var users = [ {id:1, name:"User1", email:"user1@gmail.com", age:31}, {id:2, name:"User2", email:"user2@gmail.com", age:20}, {id:3, name:"User1", email:"user1.2@gmail.com", age:25}];module.exports= {index:function(req, res) {res.render('users/index',{ users: users }); },search:function(req, res) {var name_search =req.query.name // lấy giá trị của key name trong query parameters gửi lênvar age_search =req.query.age // lấy giá trị của key age trong query parameters gửi lênvar result =users.filter( (user) => {// tìm kiếm chuỗi name_search trong user name. // Lưu ý: Chuyển tên về cùng in thường hoặc cùng in hoa để không phân biệt hoa, thường khi tìm kiếmreturnuser.name.toLowerCase().indexOf(name_search.toLowerCase()) !==-1&&user.age ===parseInt(age_search) })res.render('users/index', { users: result // render lại trang users/index với biến users bây giờ chỉ bao gồm các kết quả phù hợp }); },get_create:function(req, res) {res.render('users/create'); },post_create:function(req, res) {users.push(req.body);res.redirect('/users') },show:function(req, res) {var user =users.find( (user) => {returnuser.id ==parseInt(req.params.id); });res.render('users/show', { user: user }) }};
constexpress=require('express');constuser_router=express.Router();// Require user controllerconstuser_controller=require('../controllers/user');user_router.get('/',user_controller.index) // Lấy hàm ở key indexuser_router.get('/search',user_controller.search)user_router.get('/create',user_controller.get_create)user_router.post('/create',user_controller.post_create)user_router.get('/:id',user_controller.show)// Exports cho biến user_routermodule.exports= user_router;
Như vậy, đoạn code đã trở nên gọn gàng, dễ sử dụng, nâng cấp hơn đúng không nào. Thông qua bài này, hy vọng các bạn đã nắm được về controller. Hẹn gặp lại các bạn trong bài sau