MVC(Model-View-Controller)是一种常用的软件开发设计模式,它将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller)。MVC 可以提高代码的可读性、可维护性和可重用性,同时也可以让开发人员更好地协同开发。
Express.js 是 Node.js 中最流行的 Web 框架之一,它允许您使用 MVC 模式来组织您的应用程序代码。在本文中,我们将探讨 Express.js 中的 MVC 模式,包括如何在 Express.js 中设置 MVC 结构,以及如何使用它来编写更好的代码。
MVC 的工作原理
在 MVC 模式中,应用程序被分为三个主要部分:
- Model:模型类主要是与数据源进行交互,包括数据库、API 接口等。
- View:视图类主要是与用户交互,负责将模型类返回的数据展示给用户。
- Controller:控制器类主要是处理用户的请求,并将请求传递给模型类和视图类,以及将响应数据返回给用户。
下图展示了 MVC 模式的工作原理:
当用户发起请求时,请求将首先被路由器捕获并传递给控制器类。控制器类将请求处理得更具体,并根据需要将请求传递给模型类和视图类。
模型类使用数据源进行交互(如数据库、API 接口等),并执行所需的操作(如添加、查询、更新和删除)。模型类将处理好的数据返回给控制器类。
视图类接收控制器传递过来的数据,并将数据呈现给用户。视图类可以是 HTML 文件、JSON 数据或任何其他响应类型。当视图类呈现了响应数据,并将其发送回客户端时,请求完全处理完毕。
Express.js 中的 MVC 结构
在 Express.js 中设置 MVC 模式并不难。通常,我们将控制器类和视图类放置在不同的文件夹中,并在 app.js 文件或路由器文件中设置路由。
以下是一个基本的 MVC 结构:
project ├── node_modules ├── views │ ├── index.html ├── controllers │ └── index.js ├── app.js └── package.json
在这个结构中,我们将应用的视图(HTML 文件)存储在 views 文件夹中,我们将控制器存储在 controllers 文件夹中。我们将 app.js 文件作为主要入口点,并在这里设置路由器。
以下是一个简单的控制器示例:
// controllers/index.js exports.getIndex = (req, res) => { res.render('index'); };
在上面的示例中,getIndex
控制器返回名为 index.html
的视图。视图位于 views 文件夹中,这意味着它们可以从控制器中轻松呈现。
以下是一个简单的路由器示例:
// app.js const express = require('express'); const controller = require('./controllers/index'); const app = express(); app.set('view engine', 'html'); app.engine('html', require('ejs').renderFile); app.use(express.static(__dirname + '/public')); app.get('/', controller.getIndex); app.listen(3000, () => { console.log('Server is running on port 3000'); });
在上面的示例中,我们设置了路由器,将控制器和视图结合在一起,并通过端口 3000 启动了我们的服务器。
实际应用
现在,我们已经了解了 MVC 模式的工作原理和在 Express.js 中设置 MVC 结构的方式,接下来我们将深入探讨如何在实际应用中使用 MVC 模式。
模型类
在大部分应用程序中,模型类通常是与数据库进行交互。作为开发人员,我们需要考虑如何封装数据交互层,以减少代码复杂度。我们可以使用 ORM(Object-Relational Mapping)工具来处理数据库的增删改查,以简化相关操作。
以下是一个基本的模型示例:
// models/Todo.js const mongoose = require('mongoose'); const todoSchema = new mongoose.Schema({ title: { type: String, required: true }, completed: { type: Boolean, default: false } }); module.exports = mongoose.model('Todo', todoSchema);
在上面的示例中,我们定义了一个名为 Todo
的模型类,并定义了它有两个字段:title
和 completed
。我们使用 Mongoose 来定义模型类,并将其导出供其他文件使用。
控制器类
在控制器类中,我们通常需要处理用户的请求并将请求传递给相应的模型类。控制器负责响应请求并将数据呈现给用户。
以下是一个基本的控制器示例:
// controllers/TodoController.js const Todo = require('../models/Todo'); exports.index = async (req, res) => { const todos = await Todo.find(); res.render('todos', { todos }); }; exports.create = async (req, res) => { const todo = new Todo({ title: req.body.title, }); await todo.save(); res.redirect('/todos'); }; exports.update = async (req, res) => { const id = req.params.id; const todo = await Todo.findById(id); todo.completed = !todo.completed; await todo.save(); res.redirect('/todos'); }; exports.delete = async (req, res) => { const id = req.params.id; await Todo.findByIdAndDelete(id); res.redirect('/todos'); };
在上面的示例中,我们定义了一个 TodoController
类,并为 index
、create
、update
和 delete
创建了方法。这些方法将请求提供给模型类并为用户呈现响应数据。
视图类
最后,我们需要编写视图类来响应用户请求并呈现数据。视图类通常是 HTML 文件,但也可以是任何其他响应类型,如 JSON 或 XML 数据。
以下是一个基本的视图示例:
<!-- views/todos.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Todo List</title> </head> <body> <h1>Todo List</h1> <ul> <% todos.forEach(todo => { %> <li> <a href="/todos/<%= todo._id %>/update"> <%= todo.title %> <% if (todo.completed) { %> [completed] <% } %> </a> <form method="post" action="/todos/<%= todo._id %>/delete"> <button type="submit">Delete</button> </form> </li> <% }) %> </ul> <form method="post" action="/todos"> <input type="text" name="title" placeholder="Add a new todo" /> <button type="submit">Add</button> </form> </body> </html>
在上面的示例中,我们使用 EJS(Embedded JavaScript)进行视图渲染。我们使用 EJS 的模板语法处理循环和条件语句。在这个示例中,我们展示了一个简单的待办事项列表,并提供了一个表单以添加新的待办事项。我们还提供了更新和删除操作,以便用户可以修改或删除待办事项。
总结
MVC 模式提供了一种强大的方法来组织应用程序代码,并使代码更具可读性、可维护性和可重用性。在 Express.js 中使用 MVC 模式非常简单,只需要将控制器类和视图类存储在不同的文件夹中,并在路由器文件中设置路由即可。
我们可以使用 ORM 工具来处理与数据库的交互,以简化相关操作。控制器负责处理用户的请求并将请求传递给相应的模型类。视图负责响应用户的请求并将数据呈现给用户。这些组件一起协同工作,组成了一个完整的 MVC 应用程序架构。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b4d7b7add4f0e0ffdb3748