Express.js 中的 MVC 模式详解

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 结构:

在这个结构中,我们将应用的视图(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 的模型类,并定义了它有两个字段:titlecompleted。我们使用 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 类,并为 indexcreateupdatedelete 创建了方法。这些方法将请求提供给模型类并为用户呈现响应数据。

视图类

最后,我们需要编写视图类来响应用户请求并呈现数据。视图类通常是 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