[英]How do I get the value of the parent into its children function in JavaScript?
I am creating a Router based on Express Router that will function like Laravel's.我正在创建一个基于 Express Router 的路由器,它的功能类似于 Laravel。
I want to be able to write code like:我希望能够编写如下代码:
Route.group("/api", () => {
Route.get("/auth/login", myLoginFunction)
Route.get("/auth/register", myRegisterFunction)
})
But how do I find out which group the routes are called under?但是我如何找出路由在哪个组下调用? My Route class looks like this:
我的 Route 类如下所示:
export class Route {
#routes: Array<IRoute>;
public static group(name: string, cb: Function) {
}
public static get(name: string, cb: Function) {
}
}
And I was thinking I would prepend the group name to each route, but I don't know how to access group name in each subroute.我想我会在每条路线前面加上组名,但我不知道如何在每个子路线中访问组名。 Any suggestions?
有什么建议么?
You can define static variable(s) before calling group callback for configuration of the groups, like prefix
.您可以在调用组回调以配置组之前定义静态变量,例如
prefix
。
Minor changes to your template include:对模板的细微更改包括:
#routes
static, otherwise it won't be accessible without instantiating Route
#routes
静态,否则不实例化Route
将无法访问public
keyword. public
关键字。 <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> class Route { static #prefix=''; static #routes = []; // if using express.Router in backend. // static #expressRouter = express.Router(); // prepare config variables for group static #prepareGroup(name: string = '') { Route.#prefix=name; Route.#prefix += name.endsWith('/') ? '' : '/'; } static group(name: string, cb: Function) { Route.#prepareGroup(name); cb(); Route.#prepareGroup(); } static get(name: string, cb: Function) { Route.#routes.push({ path: `${Route.#prefix}name`, method: 'GET', cb }); // or if using `expressRouter`, use instead // expressRouter.get(name, cb); } static _showRoutes() { console.log(Route.#routes); } } // dummy functions const myLoginFunction = () => {} const myRegisterFunction = () => {} Route.group("/api", () => { Route.get("/auth/login", myLoginFunction) Route.get("/auth/register", myRegisterFunction) }) Route._showRoutes() </script>
I found a versatile solution after looking at how AdonisJS implemented the router.在查看了 AdonisJS 如何实现路由器后,我找到了一个通用的解决方案。 Here's my final code for reference, and is used like so:
这是我的最终代码供参考,使用方式如下:
import {Router} from "fastia/kernel/RouteServiceProvider";
Router.group("api", () => {
Router.group("auth", () => {
Router.get("login", (_, res) => {
return res.send({
message: "hello"
})
}).middleware(["has:testquery", "admin"])
Router.get("register", () => null).middleware(["has:funquery"])
Router.group("password", () => {
Router.get("forgot", () => null)
Router.get("reset", () => null)
})
})
Router.get("test", () => null)
})
Router code:路由器代码:
import {Router as ExpressRouter} from "express";
import {IMiddlewareCollection} from "../middleware/IMiddleware";
export class RouteGroup {
public routes: (Route | RouteGroup)[] = [];
public name;
constructor(name: string) {
this.name = name;
}
public populate(route: (Route | RouteGroup), params: string) {
if (route instanceof RouteGroup) {
route.routes.forEach(child => this.populate(child, params));
return;
}
route.prefix(params);
}
}
export class Route {
public prefixes: string[] = [];
public path: string;
public method: string;
public handler: Function;
public middlewares?: Array<string>;
constructor(path: string, method: string, handler: Function, middlewares?: Array<string>) {
this.path = path;
this.method = method;
this.handler = handler;
this.middlewares = middlewares;
this.prefixes.push(this.path)
}
public prefix(path: string) {
this.prefixes.unshift(path);
}
public getPath() {
return "/" + this.prefixes.join("/")
}
public middleware(middlewares: Array<string>) {
this.middlewares = middlewares;
}
}
export class Router {
public routes: (Route | RouteGroup)[] = [];
public openedGroups: Array<RouteGroup> = [];
private router: ExpressRouter = ExpressRouter();
private middlewareCollection: IMiddlewareCollection;
public static instance: Router;
public setMiddlewares(middlewareCollection: IMiddlewareCollection) {
this.middlewareCollection = middlewareCollection;
}
private getRecentGroup() {
return this.openedGroups[this.openedGroups.length - 1];
}
private route(path: string, method: string, handler: Function) {
const route = new Route(path, method, handler);
const openedGroup = this.getRecentGroup();
if (openedGroup) {
openedGroup.routes.push(route)
} else {
this.routes.push(route)
}
return route;
}
public _get(path: string, handler: Function) {
return this.route(path, "get", handler);
}
public _group(name: string, cb: Function) {
const group = new RouteGroup(name);
const openedGroup = this.getRecentGroup();
if (openedGroup) {
openedGroup.routes.push(group)
} else {
this.routes.push(group);
}
this.openedGroups.push(group);
cb();
this.openedGroups.pop();
group.populate(group, group.name);
}
public static group(name: string, cb: Function) {
return this.getInstance()._group(name, cb);
}
public static get(path: string, handler: Function) {
return this.getInstance()._get(path, handler);
}
private parseRoute(route: (Route | RouteGroup)) {
if (route instanceof RouteGroup) {
route.routes.forEach(child => this.parseRoute(child))
} else {
console.log(route.getPath());
if (route.middlewares?.length) {
const middlewares: Function[] = [];
route.middlewares.forEach(x => {
if (this.middlewareCollection[x]) {
middlewares.push(this.middlewareCollection[x].handle);
}
})
this.router[route.method](route.getPath(), ...middlewares, route.handler);
} else {
this.router[route.method](route.getPath(), route.handler);
}
}
}
public run() {
this.routes.forEach(route => this.parseRoute(route));
}
public getRouter() {
return this.router
}
public static create() {
this.instance = new this();
return this.instance
}
public static getInstance() {
return this.instance
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.