Egg.js 中 Controller 的使用

news2025/1/15 20:43:20

如果需要了解Controller ,就得知道什么是mvc。

MVC概述

什么是mvc,这个概念,我相信绝大部分人肯定是了解的。MVC是模型(model)- 视图(view)- 控制器(controller)的缩写。MVC是一种软件设计规范,主要作用就是逻辑拆分:

  • 视图为用户展示数据
  • 控制器用来处理用户输入
  • 模型用户数据处理

ps:这一整套流程实际上是一个闭环,你可以这么去理解,就是用户输入给控制器,然后控制器将用户输入的指令和数据传递给业务组件,业务组件进行业务逻辑判断,数据库存取,将要展示的数据返回到视图,用户得到了反馈,在进行下一步的操作。

Egg中的控制器(controller)

  • 直接响应数据或渲染模板
  • 接受用户输入
  • 与路由器建立对应关系

this.ctx可以获取到当前请求的上下文对象,通过此对象可以便捷的获取到请求与响应的属性与方法。

我们可以拿最初的模板案例来解析,controller文件夹下面的home.js文件:

'use strict'; //严格模式

const Controller = require('egg').Controller; //Controller类

class HomeController extends Controller { //定义一个新的类去继承Controller类
  async index() {
    const { ctx } = this;
    ctx.body = '你好egg';
  }
}

module.exports = HomeController; //暴露HomeController

这个严格模式,写和不写都可以,没必要说一定要写,这个也不是egg特有的,因为egg已经给我们封装好了控制器的方法,所以我们只需要调用就好了,然后继承暴露出来,最简单的一个控制器我们就写好了。

接下来,尝试写一个水果控制器,首先要在controller文件夹下创建fruits.js,然后我们模仿home.js进行编写。

'use strict'; //严格模式

const Controller = require('egg').Controller; //Controller类

class FruitsController extends Controller {
  async index() {
    this.ctx.body = '我是一个水果列表'
  }
}
module.exports = FruitsController

此时,我们写完,想要去访问这个页面,肯定是需要路由去访问的,所以,我们需要去编写router.js这个文件,来访问我们刚刚写的水果页面。

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/fruits', controller.fruits.index);
};

通过这个代码,我们可以看出来,这个是通过暴露一个函数,这个app是一个形参,是egg应用里的一些实例。

然后通过结构赋值的方法,我们拿到了,router和controller这两个对象。

然后通过路由的get方法去规定跳转的路由地址,以及展示的是controller目录下面的home文件里的index方法。

所以我们访问地址是’/‘看到的就是’hi,egg’,所以我们模仿一下,加上router.get(‘/fruits’, controller.fruits.index); 就能通过访问’/fruits’实现访问上面写的水果页面了。

image.png

通过路由传递参数

  • 获取query参数
  • 获取params参数

获取query参数的get请求方法

我们在控制器里靠一个属性去获取get请求的query,this.ctx.request.query,然后我们只要在url后面拼上传递的数据,就能获取到了,http://127.0.0.1:7001/fruits?index=100

'use strict'; //严格模式

const Controller = require('egg').Controller; //Controller类

class FruitsController extends Controller {
  async index() {
    let query = this.ctx.request.query
    this.ctx.body = `传递的index的值是${query.index}`
  }
}
module.exports = FruitsController

image.png

params参数的get请求方法

首先我们要在router.js里面加上一行router.get(‘/fruits/:id’, controller.fruits.getId),我们重新写一个getId的方法。

async getId() {
    let id = this.ctx.params.id
    this.ctx.body = `传递的id的值是${id}`
}

然后我们只要在url后面加上’/100’就能获取到了,http://127.0.0.1:7001/fruits/100

image.png

拓展:那么如果你想传多个参数,就继续往后面拼就可以了router.get(‘/fruits/:id/:title’, controller.fruits.getId),拿的话,也和上面一样let title = this.ctx.params.title。

query和params的post请求

说完了query以及params的get请求呢,接下来就是query和params的post请求了,这个稍微难一点。获取post请求参数:this.ctx.request.body。

举个例子实现,表单提交是post请求,我们可以通过实现表单提交来获取post的参数,那么,我们可以通过提交表单,插入数据到列表里面。

第一步:要创建数组,和类同级

let fruitList = ["香蕉", "苹果", "西瓜"]

第二步:有了数组,我们就需要一个页面去展示这个数组

async getList() {  //获取水果列表
    this.ctx.body = fruitList
}
router.get('/fruitList', controller.fruits.getList);

image.png

第三步:构建表单页面

async createPage() {   //提交表单
    this.ctx.body = `
    <form>
    <input name="fruitName">
    <button>添加</button>
    </form>
    `
}
router.get('/createPage', controller.fruits.createPage);

image.png

第四步:我们需要输入,然后将输入的内容插入到水果列表里面,首先我们要修改一下createPage方法,加入请求方法为post,提交的地址也要加上。

async createPage() {
    this.ctx.body = `
    <form method='post' action='/creatFruit'>
    <input name="fruitName">
    <button>添加</button>
    </form>
    `
}

async creatFruit() {  //获取提交的水果数据
    let fruit = this.ctx.request.body  
    this.ctx.body = fruit
 }
router.post('/creatFruit', controller.fruits.creatFruit);

第五步:输入水果,提交表单,发现,页面显示403

image.png

之所以有这个情况,是因为CSRF指跨站请求伪造,Egg中对post请求做了一些安全验证,可以在config.default.js文件中,通过下面的设置验证。

config.security = {
      csrf:{
          enable:false
    }
}

配置好这个,我们再次输入水果,再次点击提交,此时,我们成功跳转到了’/createFruit’页面

image.png

第六步:也就是最后一步,我们需要提交跳转的页面,将数据插入到原先的列表里面去

async creatFruit() {
    let fruit = this.ctx.request.body
    fruitList.push(fruit.fruitName)
    this.ctx.body = '添加成功'
}

此时,我们输入提交会出现 ‘添加成功’的字样,然后我们在跳转会’/fruitList’就会看到输入的内容已经被插入了

image.png

//fruits.js
'use strict'; //严格模式

const Controller = require('egg').Controller; //Controller类
let fruitList = ["香蕉", "苹果", "西瓜"]
class FruitsController extends Controller {

  //index方法  用于获取query的get请求参数
  async index() {
    let query = this.ctx.request.query
    this.ctx.body = `传递的index的值是${query.index}`
  }

  //getId方法  用于获取params的get请求参数
  async getId() {
    let id = this.ctx.params.id
    let title = this.ctx.params.title
    this.ctx.body = `传递的id的值是${id},传递的title是${title}`
  }

  //getList方法  用于展示水果列表
  async getList() {
    this.ctx.body = fruitList
  }

  //createPage方法  用于表单提交页面
  async createPage() {
    this.ctx.body = `
    <form method='post' action='/creatFruit'>
    <input name="fruitName">
    <button>添加</button>
    </form>
    `
  }

  //插入提交的水果
  async creatFruit() {
    let fruit = this.ctx.request.body
    fruitList.push(fruit.fruitName)
    this.ctx.body = '添加成功'
  }

}
module.exports = FruitsController
//router.js
'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const {
    router,
    controller
  } = app;
  router.get('/', controller.home.index); //默认页
  router.get('/fruits', controller.fruits.index);
  router.get('/fruits/:id/:title', controller.fruits.getId)
  router.get('/fruitList', controller.fruits.getList);
  router.get('/createPage', controller.fruits.createPage);
  router.post('/creatFruit', controller.fruits.creatFruit);
};

到这里,post的请求方法拿参数完成了,不过,往回看路由,会发现,我们写的很多,get写一个,post写一个,如果后面说,一个地址里面,引入了好多的方法,那会越写越多,所以这里egg为了简单写法,给出了新的形式。

RESTful风格的URL定义

restful风格的url可以简化路由文件
格式:app.router.resources(‘routerName’, ‘pathMatch’, controller)

router.resources('posts','/api/posts',controller.posts) //一个方法同时定义增删改查

image.png

我们来简化一下之前的路由,全部隐藏,你可以删除,然后写上

router.resources('fruits', '/fruits', controller.fruits)

根据表格的对对照关系,我们将fruits.js修改一下

async index() {
    this.ctx.body = fruitList
}

async new() {
    this.ctx.body = `
    <form method='post' action='/fruits'>
    <input name="fruitName">
    <button>添加</button>
    </form>
    `
}

async create() {
    let fruit = this.ctx.request.body
    fruitList.push(fruit.fruitName)
    this.ctx.body = '添加成功'
}

首先这个index方法,对应表格里面的get请求,就把之前的getList的方法内容移到index方法里面

就是index方法专门去获取水果列表,表里对应的new方法,放表单的提交内容

有一点要注意,就是我们提交时候的action地址要变成router.js里面写的地址,creat方法对应的是post请求,所以我们放拿到参数的一系列操作。然后我们回到页面,在地址栏上输入’/fruits’,就能看到列表,输入’/fruits/new’,就会来到提交表单页面。

最后我们完善一下这个demo,添加成功,返回到水果列表的页面,我们只需要用this.ctx.redirect(‘/fruits’)就能重定向到水果列表页面

//router.js
'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const {
    router,
    controller
  } = app;
  router.get('/', controller.home.index); //默认页
  router.resources('fruits', '/fruits', controller.fruits)
};
//fruits.js
'use strict'; //严格模式

const Controller = require('egg').Controller; //Controller类
let fruitList = ["香蕉", "苹果", "西瓜"]
class FruitsController extends Controller {

  //index方法  用于获取query的get请求参数
  async index() {
    this.ctx.body = fruitList
  }

  //createPage方法  用于表单提交页面
  async new() {
    this.ctx.body = `
    <form method='post' action='/fruits'>
    <input name="fruitName">
    <button>添加</button>
    </form>
    `
  }

  //插入提交的水果
  async create() {
    let fruit = this.ctx.request.body
    fruitList.push(fruit.fruitName)
    //跳转到/fruits get请求
    this.ctx.redirect('/fruits')
  }
}
module.exports = FruitsController

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1149254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git跳过用户名密码验证,以及配置credential-helper

平时我们在使用git命令时&#xff0c;如果使用http方式拉取代码每次都需要使用填写用户名和密码&#xff0c;非常的麻烦。 如何才能绕过每次繁琐的填充? 如果想要绕过git的交互方式&#xff0c;首先需要了解git的密码存储机制。 git使用的使用是一种名叫**[credential helpe…

ssm搭建后404的错误

spring、mybatis 的配置文件一般不会出错&#xff08;注解扫描路径要涵盖 controller层&#xff09;&#xff0c;controller 层 url 一般也不会写错&#xff0c;出现404&#xff0c;更容易忽略的是 文件路径位置。 首先是 idea 提示 servlet-mapping 找不到 , 我这里显然是有的…

Java-PriorityQueue 优先队列(结构与用法)

1. 数据结构 1.1 2.Java使用 2.1 核心要点 PriorityQueue是一个无限制的队列&#xff0c;并且动态增长。默认情况下&#xff0c;优先级队列的对象按自然顺序排序。PriorityQueue 不是线程安全的。多线程情况下可以使用PriorityBlockingQueue。 2.2 构造函数 PriorityQueu…

如何去掉Word文档中蓝色和红色波浪线

在Word2013文档中有些文字或者字母的下面会出现一些红色或蓝色的波浪线&#xff0c;这是因为Word会自动检查文档中拼写和语法错误所造成的&#xff0c;那么如何去掉这些蓝色红色的波浪线呢&#xff1f;下面就跟大家分享一下方法。 工具/原料 Word2013 方法/步骤 1 首先打开一个…

Widget必须在GUI线程中创建

背景&#xff1a;miniblink的vip版本&#xff0c;下载功能是独立线程&#xff0c;我希望在下载后弹出窗口&#xff0c;就在其中创建了QWidget子类对象。然后出现了上面的错误。 解决方法&#xff1a; 使用信号和槽来处理。 具体来讲&#xff0c;在独立线程中创建QObject子类…

【波形图】LabVIEW中的波形图和波形图表有什么区别?

波形图和波形图表在显示和更新数据的方式上有所不同。 波形图可接受各种类型的数据阵列&#xff0c;例如数组&#xff0c;波形或动态数据。波形图在接收到数据后将立即绘制所有接收到的数据点 。波形图不接受单点值。当您将包含数据点的数组连接到波形图时&#xff0c;波形图会…

深度学习中的FPN详解

深度学习入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 目录 一、FPN提出原因 二、FPN的参考思想 三、特征金字塔 四、FPN具体思路 一、FPN提出原因 卷积网络中&#xff0c;深层网…

IDEA 使用技巧

文章目录 语言支持简化编写 有问题&#xff0c;可暂时跳过 个人常用快捷键插件主题插件功能插件 碰到过的问题 除了一些在Linux上用vim开发的大佬&#xff0c;idea算是很友好的集成开发工具了&#xff0c;功能全面&#xff0c;使用也很广泛。 记录一下我的 IDEA 使用技巧&#…

省钱兄短剧短视频视频滑动播放模块源码支持微信小程序h5安卓IOS

# 开源说明 开源省钱兄短剧系统的播放视频模块&#xff08;写了测试弄了好久才弄出来、最核心的模块、已经实战了&#xff09;&#xff0c;使用uniapp技术&#xff0c;提供学习使用&#xff0c;支持IOSAndroidH5微信小程序&#xff0c;使用Hbuilder导入即可运行 #注意&#xff…

1.2 OSI安全架构

思维导图&#xff1a; 1.2 OSI安全架构 为了有效评估组织的安全需求并选择合适的安全产品和政策&#xff0c;安全管理员需要系统化地定义安全需求并描述满足这些需求的措施。这在集中式数据处理环境下就已经很困难&#xff0c;而在今天使用的局域网和广域网中更是如此。 OSI安…

Undefined reference错误处理及Linux设置动态链接库so的默认搜索路径

文章目录 1 问题的提出2 问题的分析3 问题的解决3.1 Windows的VS修改配置属性3.2 Linux系统里添加搜索路径json在/usr/llib目录中libcryto.so在/usr/lib64文件夹中 Linux设置动态链接库so的默认搜索路径方法一&#xff1a;修改 ld.so.conf 文件方法二&#xff1a;修改环境变量方…

3分钟搞定腾讯云轻量应用服务器和云服务器的区别

腾讯云轻量服务器和云服务器有什么区别&#xff1f;为什么轻量应用服务器价格便宜&#xff1f;是因为轻量服务器CPU内存性能比云服务器CVM性能差吗&#xff1f;轻量应用服务器适合中小企业或个人开发者搭建企业官网、博客论坛、微信小程序或开发测试环境&#xff0c;云服务器CV…

CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局

一、概述 操作系统是计算机系统的核心软件&#xff0c;它管理和控制着计算机的硬件和软件资源&#xff0c;为用户和应用程序提供了一个统一、高效、安全的运行环境。操作系统的发展历史也是计算机技术的发展历史的重要组成部分&#xff0c;它见证了计算机从单机到网络&#xf…

GaussDB SQL基础语法示例-常见的条件表达式

目录 一、前言 二、条件表达式的概念及GaussDB中的常见条件表达式 三、GaussDB中常用的条件表达式&#xff08;语法 示例&#xff09; 1、CASE表达式 2、DECODE表达式 3、COALESCE表达式 4、NULLIF表达式 5、GREATEST/ LEAST表达式 6、NVL表达式 四、小结 一、前言 …

聚观早报 |蔚来推出婚车服务;长城汽车第三季度财报

【聚观365】10月30日消息 蔚来推出婚车服务 长城汽车第三季度财报 AI汽车机器人极越01上市 谷歌投资初创公司Anthropic 东方财富第三季度营收 蔚来推出婚车服务 据蔚来汽车官方消息&#xff0c;蔚来宣布推出“蔚来用户专享”的婚庆用车定制服务。 据悉&#xff0c;该服务…

Web3风险不可回避,欧科云链携手FT中文、港大重塑行业信心

在香港Web3.0行业&#xff0c;技术推动了虚拟资产投资市场的快速增长&#xff0c;但另一方面&#xff0c;JPEX诈骗案等行业风险事件也接连发生&#xff0c;为Web3行业发展提供了重要警示。在刚刚结束的香港立法会施政报告答问会上&#xff0c;行政长官李家超表示&#xff0c;与…

三相电机输入线电流与输出功率之间的理论曲线

1.首先取一组电机参数&#xff1a; 定子电阻&#xff1a;11.421欧转子电阻&#xff1a;7.553欧漏感抗&#xff1a;42.90 毫亨互感抗&#xff1a;553.9毫亨空载电流&#xff1a;1.17安。 2. 利用T型等效电路公式绘图&#xff1a; import numpy as np import matplotlib.pyplot …

c语言数据类型的定义

c语言数据类型的定义 c语言数据类型的定义 c语言数据类型的定义一、数据类型的定义二、变量三、常量 一、数据类型的定义 数据类型的定义 在计算机中&#xff0c;不同的数据所需占用的存储空间是不同的&#xff0c;为了便于把数据分成所需内存大小不同的数据&#xff0c;充分利…

OceanBase安装部署

OceanBase自动化安装部署OBD 前提条件一、 OceanBase 集群部署规划1、创建用户2、规划目录 二、安装OceanBase环境1、 方案一&#xff1a;若机器能联网执行如下命令在线下载并安装 all-in-one 安装包2、 方案二&#xff1a;若机器不能联网需要在官网下载 all-in-one安装包&…

8+双疾病+WGCNA+多机器学习筛选疾病的共同靶点并验证表达

今天给同学们分享一篇双疾病WGCNA多机器学习的生信文章“Shared diagnostic genes and potential mechanism between PCOS and recurrent implantation failure revealed by integrated transcriptomic analysis and machine learning”&#xff0c;这篇文章于2023年5月16日发表…