简体   繁体   English

如何在 JavaScript 中将父级的值放入其子级函数中?

[英]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:对模板的细微更改包括:

  1. keep #routes static, otherwise it won't be accessible without instantiating Route保持#routes静态,否则不实例化Route将无法访问
  2. Javascript doesn't have public keyword. Javascript 没有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.

相关问题 如何在事件侦听器中将父节点与其所有子节点相关联? jQuery / JavaScript - How do I associate a parent node with all of its children in an event listener? jQuery / JavaScript 如何使用Javascript获取所有孩子(即孩子的孩子)? - How do i get all children (ie children of children) with Javascript? 如何在不向其父/子项添加逻辑的情况下获取组件中子元素的dom节点? - How do I get the dom node of a child element in a component without adding logic to its parent/children? 如何让我的 Javascript function 正确使用其输入值? - How do I get my Javascript function to use its input value correctly? 我如何在javascript中引用子函数中的父对象值 - how do i refer to the parent object value in child function in javascript 当孩子们这样做时,我如何让父 div 调整大小? - How do I get a parent div to resize when the children do? 如何获得功能的“孩子”或内容? - How do I get the “children” or contents of a function? 如何获取函数中父标记的属性值? - How do i get attribute value of the parent tag in a function? 如何仅获取父元素的可见子元素? - How do I get only the visible children elements of a parent element? 如何获得父div中子代的总和? - How do I get the sum of children within a parent div?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM