控制器

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

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

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

创建控制器

使用thinkkoa_cli命令行工具:

单模块模式:

think controller index

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

多模块模式:

think controller admin/index

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

控制器模板代码如下:

const {controller, helper} = require('thinkkoa');

module.exports = class extends controller {
    //构造方法init代替constructor
    // init(ctx, app) {

    // }
    //所有该控制器(含子类)方法前置方法
    __before() {
        console.log('__before');
    }
    //URI定位到该控制器,如果该控制器不存在某个方法时自动调用
    __empty() {
        return this.json('can\'t find action');
    }
    //indexAction前置方法
    _before_index() {
        console.log('_before_index');
    }
    //控制器默认方法
    indexAction() {
        return this.ok('success');
    }
};

继承

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

构造方法

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

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

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

前置操作

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

公共前置方法:

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

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

__before(){
    console.log('__before');
}

indexAction(){
    console.log('indexAction');
}
//控制台打印
__before
indexAction

独有前置方法:

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

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

__before(){
    console.log('__before');
}

_before_index(){
    console.log('_before_index');
}

indexAction(){
    console.log('indexAction');
}

//控制台打印
__before
_before_index
indexAction

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

空操作

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

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

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

空操作对应的方法:

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

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

访问控制

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

const {controller, helper}
module.exports = class extends controller {

    //构造方法init代替constructor
    // init(ctx, app) {

    // }

    test() { //不包含后缀,无法被URL直接访问
        ...
    }
}

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

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

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

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

属性及方法

见文档章节API/controller