繼續(xù)朝刊!
首先我們在ts中使用decorator伴挚,需要修改以下tsconfig.json文件
字面意思垃环,就是開啟裝飾器功能军浆,和定義元數(shù)據(jù)信息的功能
編寫代碼
在src文件夾下創(chuàng)建以下四個文件:
- index.ts入口文件
- router.ts路由文件
- decorator.ts裝飾器文件
-
controller控制器文件
index.ts中坯门,代碼很簡單就是引入路由,引入控制器逗扒,使用路由即可
import express, { Application} from "express"
import http from "http"
import {router} from "./router";
import "./TestController"
const app: Application = express()
app.use(router)
//這種是express的源碼寫法田盈,跟你們以前看到的app.listen是一摸一樣的功能
http.createServer(app).listen(3030, () => {
console.log("server is running at http://localhost:3030")
})
router.ts中,也很簡單缴阎,創(chuàng)建路由,并暴露出去
import {Router} from 'express';
export const router: Router = Router()
接下來是最重要的decorator.ts文件
import 'reflect-metadata';
import {router} from './router'
enum Method {
get = 'get',
post = 'post',
delete = 'delete',
put = 'put'
}
export function controller(target: any) {
for (let key in target.prototype) {
const path:string = Reflect.getMetadata('path', target.prototype, key)
const method :Method= Reflect.getMetadata('method', target.prototype, key)
const handler = target.prototype[key]
if (path && method && handler) {
router[method](path, handler);
}
}
}
function getRequestDecorator(type: Method) {
return function (path: string) {
return function (target: any, key: string) {
Reflect.defineMetadata('path', path, target, key);
Reflect.defineMetadata('method', type, target, key);
};
}
}
export const get = getRequestDecorator(Method.get)
export const post = getRequestDecorator(Method.post)
export const del = getRequestDecorator(Method.delete)
export const put = getRequestDecorator(Method.put)
首先看getRequestDecorator简软,這個函數(shù)跟他內(nèi)部返回的第一層函數(shù)蛮拔,其實目的都是一個,就是在class的方法的閉包中保存當前方法的method和path痹升,然后最內(nèi)層函數(shù)再返回真正的修飾器函數(shù)建炫,并在修飾器函數(shù)里定義元數(shù)據(jù)path和method
而在controller中,我們遍歷class的原型疼蛾,根據(jù)class的每個方法中的method和path去增強express的路由肛跌,跟平常用express寫路由沒有本質(zhì)區(qū)別
const router = Router()
router.get("/",(req,res)=>{res.end()})
router.post("/",(req,res)=>{res.end()})
最后TestController.ts文件,可以看到這個文件跟我們平時看到的srpingmvc框架可以說非常像了
import {Request, Response} from 'express';
import {controller, get, post} from './decorator';
@controller
class TestController {
@get("/home")
home(req: Request, res: Response) {
res.json({a: 123111})
}
@post("/data")
data(req: Request, res: Response) {
res.json("data")
}
}
測試兩個接口
最后說一些可能讓人疑惑的點
首先裝飾器是在編譯時執(zhí)行的察郁,所以我們在index.ts里只需要簡單引入TestController.ts文件衍慎,裝飾器就執(zhí)行了。
這段代碼中皮钠,裝飾器的執(zhí)行是順序是先執(zhí)行方法上的裝飾器(定義元數(shù)據(jù))稳捆,再執(zhí)行class上的裝飾器(獲取元數(shù)據(jù)并修飾router)
//我后執(zhí)行哦
@controller
class TestController {
//我先執(zhí)行哦
@get("/home")
home(req: Request, res: Response) {
res.json({a: 123111})
}
//我先執(zhí)行哦
@post("/data")
data(req: Request, res: Response) {
res.json("data")
}
}