控制器

ThinkKoa 基于 模块/控制器/操作 的设计原则:

  • 模块: 一个应用下有多个模块,每一个模块都是很独立的功能集合。比如:前台模块、用户模块、管理员模块
  • 控制器: 一个分组下有多个控制器,一个控制器是多个操作的集合。如:商品的增删改查
  • 方法: 一个控制器有多个方法,每个方法都是最小的执行单元。如:添加一个商品

注意: 默认的单模块模式下,没有模块的区分

创建控制器

使用thinkkoa_cli命令行工具:

单模块模式:

  1. think controller index

会自动创建 app/controller/index.js文件。

多模块模式:

  1. think controller admin/index

会自动创建 app/controller/admin/index.js文件。

控制器模板代码如下:

  1. const {controller, helper} = require('thinkkoa');
  2. module.exports = class extends controller {
  3. //构造方法init代替constructor
  4. // init(ctx, app) {
  5. // }
  6. //所有该控制器(含子类)方法前置方法
  7. __before() {
  8. console.log('__before');
  9. }
  10. //URI定位到该控制器,如果该控制器不存在某个方法时自动调用
  11. __empty() {
  12. return this.json('can\'t find action');
  13. }
  14. //indexAction前置方法
  15. _before_index() {
  16. console.log('_before_index');
  17. }
  18. //控制器默认方法
  19. indexAction() {
  20. return this.ok('success');
  21. }
  22. };

继承

控制器类必须继承于 thinkkoa.controller. 或 thinkkoa.controller 的子类。

构造方法

ThinkKoa 使用init() 方法来替代construct() 构造方法(construct在使用super时有限制)。

控制器里可以重载 init 方法如:

  1. //构造方法
  2. init(ctx){
  3. this.data = {};
  4. }

前置操作

ThinkKoa支持两种控制器前置操作,分别是公共前置方法以及独有前置方法

公共前置方法:

  1. //所有该控制器(含子类)方法前置方法
  2. __before(){
  3. console.log('__before');
  4. }

公共前置方法会在接收到HTTP请求后,在执行路由规则匹配的action之前执行。

  1. __before(){
  2. console.log('__before');
  3. }
  4. indexAction(){
  5. console.log('indexAction');
  6. }
  7. //控制台打印
  8. __before
  9. indexAction

独有前置方法:

独有的前置方法会在执行具体方法之前执行。

注意:init构造方法和被访问限制的方法(不带Action后缀)不支持前置操作

  1. __before(){
  2. console.log('__before');
  3. }
  4. _before_index(){
  5. console.log('_before_index');
  6. }
  7. indexAction(){
  8. console.log('indexAction');
  9. }
  10. //控制台打印
  11. __before
  12. _before_index
  13. indexAction

执行顺序为(indexAction举例): 公共前置方法(__before) —> 独有前置方法(_before_index) —> indexAction

空操作

空操作是指系统在找不到请求的操作方法的时候,会定位到空操作方法执行,利用这个机制,可以实现错误页面和一些 url 的优化。默认空操作对应的方法名为 ,可以通过下面的配置修改:

项目中间件配置 config/middleware.js:

  1. config: { //中间件配置
  2. ...,
  3. controller: {
  4. empty_action: '__empty', //空方法,如果访问控制器中不存在的方法,默认调用
  5. }
  6. }

空操作对应的方法:

  1. //URI定位到该控制器,如果该控制器不存在某个方法时自动调用
  2. __empty(){
  3. return this.json('can\'t find action');
  4. }

如果控制器下没有空操作对应的方法,那么访问一个不存在的 url 时则会报错。

访问控制

ThinkKoa默认仅暴露带 Action后缀的控制器方法给URL访问,如果控制器内方法名不包含此后缀,该方法无法被URL直接访问。

  1. const {controller, helper}
  2. module.exports = class extends controller {
  3. //构造方法init代替constructor
  4. // init(ctx, app) {
  5. // }
  6. test() { //不包含后缀,无法被URL直接访问
  7. ...
  8. }
  9. }

该后缀在中间件配置中可以自行修改:

项目中间件配置 config/middleware.js:

  1. config: { //中间件配置
  2. ...,
  3. controller: {
  4. action_suffix: 'Action', //方法后缀,带后缀的方法为公共方法
  5. }
  6. }

Action后缀可以自定义修改,具体请参考think_controller中间件配置。

属性及方法

见文档章节API/controller