Lập trình MVC trong NodeJS

Lập trình MVC trong NodeJS hướng dẫn bạn cách thức phát triển website trong NodeJS với mô hình lập trình MVC.

Đôi điều về web Framework Express

Express là module rất phổ biến trong thế giới NodeJS, nó  giúp web dev tạo nên các chức năng cơ bản cho project mà không phải thực hiện nhiều việc thủ công.  Website của express là http://expressjs.com  

Bạn nên cài đặt express ở chế độ global, để sử dụng nó cho việc tạo project ở máy local nhanh hơn. Ngoài express, module express-generator cũng hết sức cần thiết cài vào, vì nó giúp bạn phát sinh các file và folder cần dùng lúc bắt đầu project. Thực hiện cài đặt như sau:

  1. Mở command line
  2. Gõ  lệnh npm install -g express
  3. Tiếp theo gõ lệnh  npm -g install express-generator

1. Tạo project với express

Vào command line và chuyển đến folder chứa project rồi chạy lệnh:

express --ejs LabTest

Bạn sẽ thấy folder LabTest xuất hiện các folder và file trong đó

labtest
labtest_files

Trong folder project có file app.js , đây là file chính, giống file main trong C++.  Express còn tạo 2 module routes/index và routes/users để xử lý các request HTTP.  Hàm app.set() thường thấy trong code dùng để gán thông số cho project và các module. .

labtest_files-2

Như hình trên, bạn thấy các thư viện cần thiết đã được nhúng, đã set sẵn view engine cũng thiết lặp, folder views và folder public đã chỉ định. 3 controller indexRouter và usersRouter cũng đã được khai báo và chỉ định.

labtest_files-3

File www trong folder bin đã cũng đã listen sẵn ở port 3000 cho bạn.

labtest_files-4

File package.json đã chỉ định start mặc định file bin/www

2. Cài module cho project

Chuyển vào folder project rồi chạy lệnh : npm install để cài thêm các chức năng cơ bản khác nhé.

3. Chạy project

Giờ thì đã có cấu trúc folder cùng các module cơ bạn, chạy project thôi. Chạy 1 trong 2 lệnh npm start hoặc node bin/www

Test: http://localhost:3000

chay-nodejs-voi-exoress

Mô hình MVC

MVC là mô hình thường được dùng hiện nay để phát triển các webite. Vì MVC giúp tổ chức tách bạch giữa các thành phần quan trọng trong dự án:  điều khiển (controller), xử lý dữ liệu (model) và hiển thị dữ liệu (view).

Controller trong mvc

Controller được tạo ra để thực thi các yêu cầu từ user,  controller thực hiện tiếp nhận tham số, gọi các hàm trong model, nạp các view cần thiết… Trong NodeJS , routes đóng vai trò như controller.

Model trong mvc

Model dùng để cung cấp dữ liệu, thực hiện kết nối, trích lọc, chèn, chỉnh sửa dữ liệu trong database, tương tác với file system, network.

View trong mvc

Mỗi view là một trang web hiển thị dữ liệu gì đó. Dữ liệu mà view hiển thị do controller cung cấp (controller lấy từ model để đưa cho view).

Việc tách riêntg vai trò của Controler, Model và View giúp cho team phân định rõ ràng các công việc xử lý nghiệp vụ, xử lý dữ liệu và trình bày dữ liệu. Do vậy việc cập nhật chỉnh sửa một thành phần không làm ảnh hưởng đến các thành phần khác.

Mô hình MVC trong Express

Lập trình MVC trong NodeJS tức bạn sẽ tạo nên các chức năng cho website quy ước của MVC. Theo đó, các việc xử lý request, hiển thị dữ liệu , xử lý dữ liệu phải tách bạch ra theo quy định.

Module express-generator giúp bạn tạo project đã gần giống với tổ chức MVC, như folder views chứa các file view để hiện dữ liệu, folder routes dùng để xử lý các đường path chính là thành phần controller trong MVC. Bạn cần tạo thêm thành phần model nữa để xử lý dữ liệu.

Để hiểu rõ lập trình MVC trong NodeJS là thế nào, chúng ta sẽ thực hiện một ví dụ lớn nhé. Sau đây là phần hướng dẫn tạo controller, model, view để quản trị dữ liệu trong table có tên là catalog của database shop. Qua đó bạn biết 1. cách tạo controller , 2. cách tạo model, 3 cách định nghĩa hàm trong mode, 4. cách trả về giá trị từ model. 5. cách gọi model từ controller, 6. cách gọi hàm model từ controller …

table-shop

Tạo controller trong nodejs

– Tạo file routes/catalogs.js

– Định nghĩa các route cho các action sẽ thực hiện list record, addnew, store, edit, update, delete

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    res.send('Danh sách catalogs'); // GET catalogs listing.
});
router.get('/addnew', function(req, res, next) {
    res.send('Form thêm catalog'); 
});
router.post('/store', function(req, res, next) {
    //tiếp nhận dữ liệu từ form addnew để record mới vào db
});
router.get('/edit/:id', function(req, res, next) {//tham số id để biết record cần chỉnh
  var id = req.params.id;
  res.send('Form chỉnh catalog' + id);
});
router.post('/update', function(req, res, next) {
    //tiếp nhận dữ liệu từ form edit để cập nhật catalog vào db
});
router.get('/delete/:id', function(req, res) { //tham số id để biết record cần xóa
  var id = req.params.id;
  res.send('Xóa catalog');
});

module.exports = router;

– Mở app.js và thêm code khai báo route cho controller

var catalogsRouter = require('./routes/catalogs');
app.use('/cat', catalogsRouter);

Test các route , nếu thấy các chữ trong controller hiện ra là đúng.

http://localhost:3000/cat/
http://localhost:3000/cat/addnew
http://localhost:3000/cat/edit/1
http://localhost:3000/cat/delete/1
modejs-test-controller

Tới đây đã tạo controller xong , bạn biết cách tạo controller ,tạo đường dẫn cho các chức năng rồi đó.

Tạo model trong nodejs

Thành phần model giúp tương tác với các hệ thống chứa dữ liệu. Trong folder project, tạo 1 folder có tên models, mục đích để chứa các model sẽ tạo (tên folder đặt khác cũng được)

Tạo model datatabase

Chúng ta sẽ tạo model có tên là database để kết nối database nhé. Module sẽ được dùng để kết nối đến mysql.
– Trong command line, chuyển vào folder project và cài module mysql.
– Tạo file models/database.js
– Code:

//Database trả về kết nối với cơ sở dữ liệu
var mysql = require('mysql');
var db = mysql.createConnection({
   host: 'localhost', 
   user: 'root', 
   password: '', 
   database: 'shop'
}); 
db.connect(function(err) {
   if (err) throw err;
   console.log('Database is connected successfully !');
});
module.exports = db; //lệnh exports để xuất (public) ra, cho bên bên ngoài module có thể dùng được db

Tạo model catalogs

Tạo file models/catalogs.js và code định nghĩa các hàm để tương tác vào mysql

var db=require('./database');//chèn model database vào đế kết nối db
var data=[]; //biến để chứa dữ liệu đổ về cho controller
exports.create = function( nameCat, order, showHide) {
   //chèn record mới vào table catalogs
}
exports.update = function(idCat, nameCat, order, showHide) {
    //cập nhật record vào table
}
exports.detail = function(idCat) {
    //trả về 1 record từ table
}
exports.delete = function(idCat) {
    //xóa 1 record 
}

Chức năng hiện danh sách record

-Ở đầu controller catalog, chèn model catalog vào để gọi các hàm trong đó

var modelCatalogs = require('../models/catalogs'); //nhúng model vào và đặt tên model

– Trong model catalog, định nghĩa hàm list

exports.list = function() {
    let sql = `SELECT * FROM catalog`;
    db.query(sql, function(err, d) {
        if (err) throw err;        
        data= d;
    });
    return data;
}

– Code trong route / của controller catalog

router.get('/', function(req, res, next) {
  var listCat = modelCatalogs.list();//cách gọi hàm trong model, để có dữ liệu từ db
  res.render("catalog_list",{list:listCat});
});

– Tạo view: Tạo file views/catalog_list.ejs để hiển thị các record lấy được từ db

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="container col-8">
<table class="table table-bordered">
    <tr>
        <th>idCat</th>
        <th>nameCat</th>
        <th>Order</th>
        <th>Show Hide</th>
    </tr>
    <% for (let c of list ) {  %>
    <tr>
        <td><%= c.idCat %> </td>        
        <td><%= c.nameCat %> </td>
        <td><%= c.order %> </td>
        <td><%= c.showHide==1 ? "Đang hiện" : "Đang ẩn"%> </td>
    </tr>
    <% } %>
  </ul>
</div>

– Test: http://localhost:3000/cat/

lsit-catalog

Chức năng hiện form thêm mới

– Code trong route addnew của controller catalogs

router.get('/addnew', function(req, res, next) {
    //res.send('Form thêm catalog'); 
    res.render("catalog_addnew");
});

– Tạo view: Tạo file views/catalog_addnew.ejs, trong view có form với method là post và trỏ lên action store

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="container">
<form class="col-6 border border-dark rounded p-3 m-auto" action="/cat/store" method="POST">
    <div class="form-group mb-3">
        <label for="nameCat">Name Catalog</label>
        <input class="form-control bg-info" name="nameCat" id="nameCat">
    </div>
    <div class="form-group mb-3">
        <label for="Order">Order</label>
        <input class="form-control bg-primary" name="Order" id="Order">
    </div>
    <div class="form-group mb-3">
        <label>Show hide</label>
        <input type="radio" name="showHide" value="1" checked> Show  &nbsp; &nbsp; 
        <input type="radio" name="showHide" value="0"> Hide 
    </div>
    <div class="form-group mt-3 ">       
        <button type="submit" class="btn btn-dark px-4  py-2 text-white"> SAVE DATABASE </button>
    </div>
</form>    
</div>

– Test: http://localhost:3000/cat/addnew

Chức năng lưu form vào database

– Code trong route store của controller catalogs

router.post('/store', function(req, res, next) {
  let nameCat=req.body.nameCat;
  let order=req.body.Order;
  let showShide=req.body.showShide;   

  modelCatalogs.create(nameCat, order, showShide);
  res.redirect("/cat/");
})

Test lại từ form, khi submit sẽ thấy có dữ liệu mới

Chức năng hiện form edit 1 record

– Code trong route edit của controller catalogs

router.get('/edit/:id', function(req, res, next) {
  var id = req.params.id;
  var chiTietCatalog = modelCatalogs.detail(id);
  res.render("catalog_edit", {c:chiTietCatalog});
});

– Tromg model catalog, định nghĩa hàm detail:

exports.detail = function(idCat) {
    let sql = `SELECT * FROM catalog where idCat=${idCat}`;
    db.query(sql, function(err, d) {
        if (err) throw err;        
        data= d[0] ;        
    });
    return data;
}

– Tạo view: Save as file catalog_addnew. thành catalog_edit.ejs, rồi chỉnh trong thuộc tính action của form từ store thành update

– Hiện thông tin record trong form: bạn tự thực hiện nhé

– Test: http://localhost:3000/cat/edit/1

Chức năng cập nhật record vào database

– Code trong route update của controller catalogs: Bạn tự thực hiện nhé

– Test: xin mời thực hiện luôn

Chức năng xóa 1 record trong database

– Code trong route delete của controler catalog
– Code trong hàm delete của model
– Test

Như vậy Lập trình MVC trong NodeJS có khó không,đừng thấy bài dài mà nói khó nhé. Lập trình MVC trong NodeJS giúp bạn thực hiện công việc theo khuôn mẫu , nhờ đó bạn làm nhanh hơn nhiều, sự tách bạch công việc giức 3 thành phần giúp dễ dò lỗi, dễ chia việc trong team…

À, bài cần phải có kiến thức kết nối database trong NodeJS, bạn cần đọc bài Làm việc với mysql trong NodeJS trước đã nhé


Bài tập: thực hiện luyện tập mvc tương tự như bài học nhưng với table products như sau:

table-products_structure
table-products_data