【问题标题】:ES6 class method as Express router parameterES6 类方法作为 Express 路由器参数
【发布时间】:2020-03-25 22:23:17
【问题描述】:

我正在尝试将类方法作为 Express 路由参数传递,我尝试绑定该方法并且不使用箭头函数,但它也不起作用。

我正在使用 TypeORM,我得到的错误是这个“连接“默认”未找到。”,但如果我将完整的函数(如下所示)作为参数编写,一切正常。

router.get("/", async (_req: Request, res: Response) => {
    try {
        const projects: Project[] = await new ProjectService().findAll();

        res.status(200).send(projects);
    } catch (e) {
        res.status(404).send(e.message);
    }
});

下面的代码不起作用。

ProjectRoutes.ts

const router: Router = Router();

const projectController = new ProjectController();

router.get("/", projectController.getAllProjects);

export default router;

ProjectController.ts

export class ProjectController {
    projectService: ProjectService = new ProjectService();

    getAllProjects = async (_req: Request, res: Response) => {
        try {
            const projects: Project[] = await this.projectService.findAll();
            return res.status(200).send(projects);
        } catch (e) {
            return res.status(404).send(e.message);
        }
    };
}

ProjectService.ts

export class ProjectService {
    projectRepository: ProjectRepository;

    constructor() {
        this.projectRepository = getCustomRepository(ProjectRepository);
    }

    async findAll(): Promise<Project[]> {
        return await this.projectRepository.findAll();
    }
}

项目库

@EntityRepository(Project)
export class ProjectRepository extends Repository<Project> {
    async findAll(): Promise<Project[]> {
        return await this.find();
    }
}

路线索引.ts

const router: Router = Router();

router.use("/projects", ProjectRoutes);

export default router;

服务器.ts

app.use("/", router);

【问题讨论】:

  • 您遇到了什么错误?
  • 您将实例方法(使用箭头函数初始化的类字段)传递给路由器的方式应该没有问题。究竟是什么不起作用?
  • 更新问题
  • @GabrielSouza 你检查过这个吗? github.com/typeorm/typeorm/issues/4010#issuecomment-502431460 似乎与您调用 findAll() 的方式有关。
  • 如果我在 router.get 中编写完整的函数,它就可以工作,所以我认为 TypeORM 不是问题,除非我遗漏了什么,但我不知道可能是什么

标签: typescript express ecmascript-6 typeorm


【解决方案1】:

typeorm 抛出的错误 Connection "default" was not found. 通常表明您正在尝试在与 DB 建立连接之前创建存储库/使用管理器/获取连接。

在您的情况下,函数请求处理程序与类方法处理程序之间的区别在于,在函数处理程序中,您有点懒惰地初始化服务(当服务器接收到请求时)和急切地进行类内方法(在注册路由之前 - 在服务器启动阶段)。

const projectController = new ProjectController(); // <--- here you're creating an instance of controller which creates an instance of ProjectService which creates aninstance of ProjectRepository
router.get("/", projectController.getAllProjects);

我想我的建议是在构造控制器或任何依赖typeorm 东西的类之前等待建立数据库连接。

【讨论】:

  • 我不是在 ProjectController 中实例化 ProjectService 一次,而是在像“await new ProjectService().findAll();”这样的每个方法中实例化它,这样它就可以工作,因为它只获取服务/设置路由时的存储库。我现在的问题是,在每种方法中实例化是否会在将来导致问题,例如性能。
【解决方案2】:

@elderapo 指出了这个问题。您可以使用以下模式来解决问题。

ProjectController.ts

export class ProjectController {
    projectService: ProjectService = new ProjectService();

    getAllProjects = async (_req: Request, res: Response) => {
        try {
            const projects: Project[] = await this.projectService.findAll();
            return res.status(200).send(projects);
        } catch (e) {
            return res.status(404).send(e.message);
        }
    };
}

routes.ts

import {ProjectController} from './controller/ProjectController'

export const Routes = [{
    method: "get",
    route: "/",
    controller: ProjectController,
    action: "getAllProjects"
}]

index.ts

import {Routes} from "./routes";
...
createConnection().then(async connection => {

    // create express app
    const app = express();
    app.use(bodyParser.json());

    // register express routes from defined application routes
    Routes.forEach(route => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: Function) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        });
    });

    // setup express app here
    // ...

    // start express server
    app.listen(3000);
}).catch(error => console.log(error));

这是用typeorm init --name NodeStarter --database postgres --express生成的启动项目中使用的模式

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 2022-12-02
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2016-03-12
    • 1970-01-01
    相关资源
    最近更新 更多