- 最后,db.js托管我们的模拟数据库 。在实际项目中,这可能是您的实际数据库连接所在的位置 。
// db.js const db = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Joe' }, { id: 4, name: 'Jack' }, { id: 5, name: 'Jill' }, { id: 6, name: 'Jak' }, { id: 7, name: 'Jana' }, { id: 8, name: 'Jan' }, { id: 9, name: 'Jas' }, { id: 10, name: 'Jasmine' }, ] module.exports = db 正如我们所看到的,在这种架构下还有更多的文件夹和文件 。但因此,我们的代码库更加结构化和组织清晰 。一切都有自己的位置,不同文件之间的通信被明确定义 。
这种组织方式极大地方便了新功能的添加、代码修改和错误修复 。
一旦您熟悉了文件夹结构并知道在哪里可以找到每个东西,您会发现使用这些越来越小的文件非常方便,而不必滚动浏览一个或两个将所有内容放在一起的大文件 。
我还支持为您的应用程序中的每个主要实体(在我们的例子中是兔子)创建一个文件夹 。这样可以更清楚地了解每个文件的相关内容 。
假设我们现在也想添加新功能来添加/编辑/删除猫和狗 。我们将为它们中的每一个创建新文件夹,并且每个文件夹都有自己的路由、控制器和模型文件 。我们的想法是分离关注点并将每件事放在自己的位置 。
MVC 文件夹结构
MVC 是一种架构模式,代表Model View Controller 。我们可以说 MVC 架构就像是层架构的简化,也包含了应用程序的前端 (UI) 。
在这种架构下,我们将只有三个主要层:
- 视图层将负责渲染 UI 。
- 控制器层将负责定义路由和每个路由的逻辑 。
- 模型层将负责与我们的数据库进行交互 。

文章插图
和以前一样,每一层只与下一层交互,所以我们有一个明确定义的通信流 。

文章插图
描绘我们架构的另一种方式
有许多框架允许您开箱即用地实现 MVC 架构(例如Django或Ruby on Rails) 。要使用 Node 和 Express 做到这一点,我们需要像EJS这样的模板引擎 。
如果您不熟悉模板引擎,它们只是一种轻松呈现 html 的方式,同时利用变量、循环、条件等编程特性(非常类似于我们在 React 中使用 JSX 所做的) .
正如我们将在几秒钟内看到的那样,我们将为我们想要呈现的每种页面创建 EJS 文件,并且从每个控制器我们将呈现这些文件作为我们的响应,并将相应的响应传递给它们作为变量 。
我们的文件夹结构将如下所示:

文章插图
- 看到我们删除了之前的大部分文件夹并保留了db,controllers和models文件夹 。
- 我们添加了一个views文件夹,与我们要呈现的每个页面/响应相对应 。
- db.js和models.js文件保持完全相同 。
- 我们app.js看起来像这样:
// App.js const express = require("express"); var path = require('path'); const rabbitControllers = require("./rabbits/controllers/rabbits.controllers") const app = express() const port = 7070 // Ejs config app.set("view engine", "ejs") app.set('views', path.join(__dirname, './rabbits/views')) /* Controllers */ app.use("/rabbits", rabbitControllers) app.listen(port, () => console.log(`??[server]: Server is running at http://localhost:${port}`))- rabbits.controllers.js更改以定义路由,连接到相应的模型函数,并为每个请求呈现相应的视图 。看到在渲染方法中我们将请求响应作为参数传递给视图 。
// rabbits.controllers.js const express = require('express') const bodyParser = require('body-parser') const jsonParser = bodyParser.json() const { getAllItems, getItem, editItem, addItem, deleteItem } = require('../models/rabbits.models') const router = express.Router() router.get('/', (req, res) => { try { const resp = getAllItems() res.render('rabbits', { rabbits: resp }) } catch (err) { res.status(500).send(err) } }) router.get('/:id', (req, res) => { try { const resp = getItem(parseInt(req.params.id)) res.render('rabbit', { rabbit: resp }) } catch (err) { res.status(500).send(err) } }) router.put('/:id', jsonParser, (req, res) => { try { const resp = editItem(req.params.id, req.body.item) res.render('editRabbit', { rabbit: resp }) } catch (err) { res.status(500).send(err) } }) router.post('/', jsonParser, (req, res) => { try { const resp = addItem(req.body.item) res.render('addRabbit', { rabbits: resp }) } catch (err) { res.status(500).send(err) } }) router.delete('/:id', (req, res) => { try { const resp = deleteItem(req.params.idx) res.render('deleteRabbit', { rabbits: resp }) } catch (err) { res.status(500).send(err) } }) module.exports = router
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 事件驱动架构的优点和面临的挑战
- 在云端使用 Redis? 以下是你应该知道的十件事
- 20 个 Python 面试题来挑战你的知识
- 嵌入式开发如何入门?
- Spring Cloud Alibaba-全局配置自定义和支持的配置项
- MinIO OSS服务器的搭建和应用
- 陈萌|陈萌开车接朱小伟回家,介怀陈亚男的存在?称不愿做2婚妻子
- 小叶紫檀|盘点那些招财的翡翠!你有几件?
- 黄山最值得去的五个景点 黄山市旅游景点
- 职场中有效的抱怨是你晋升的阶梯
