我的意思是,假设我有这个代码:
var ARouter = Router();
@Validate({
params: {
id: joi.number(),
x: joi.number()
}
})
@HttpGet('/foo/:id')
foo(req: Request, res: Response) {
res.send('in foo').end();
}
function HttpGet(path: string) {
return function (target: ApiController, propertyName: string, descriptor: TypedPropertyDescriptor<RequestHandler>) {
ARouter.get(path, descriptor.value);
}
}
我在这里有一个路由器,装饰器和一个foo函数。 HttpGet装饰器创建一个路径'foo /:id'和foo作为ARouter中唯一的处理程序。
我希望@validate装饰器将另一个处理程序(特定的函数中间件,将在foo之前调用)添加到foo路由处理程序堆栈。 例如喜欢它是router.get('/ foo /:id /,validationFunction,foo)。
有没有办法动态地将处理程序添加到路由器中的foo路由?
谢谢!
答案 0 :(得分:0)
当多个装饰器应用于单个声明时,它们的 评价类似于数学中的函数组成。在这 模型,当组成函数f和g时,得到的复合(f∘ g)(x)等于f(g(x))。
所以你可以这样做:
function validate(params: any, fn: (req: Request, res: Response) => void) {
// validate data here and based on that decide what to do next
}
function Validate(params: any) {
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const newDescriptor = Object.assign({}, descriptor);
newDescriptor.value = function(req: Request, res: Response) {
validate(params, descriptor.value);
}
return newDescriptor;
}
}
并更改装饰者的顺序:
@HttpGet('/foo/:id')
@Validate({
params: {
id: joi.number(),
x: joi.number()
}
})
foo(req: Request, res: Response) {
res.send('in foo').end();
}
(请记住,我还没有测试过它)