为什么在TypeScript中导入用于express的路由器不起作用

时间:2018-05-28 10:53:30

标签: node.js typescript express

我正在尝试使用NodeJS和typescript建立一个简单的Hello World REST服务。我想将路由器分成不同的文件,但不知怎的,它还没有解决。

简单地说,对于http://localhost:3000/welcome/hi的GET调用,为什么项目1 有效,但项目2 不行?我试图寻找教程,但代码似乎没有按我希望的方式工作。

项目1

import express from "express";
import { Router, Request, Response } from "express";

const app: express.Application = express();
const port: any = process.env.PORT || 3000;

const router: Router = Router();
const welcomeRouter: Router = Router();

welcomeRouter.get("/", (req: Request, res: Response) => {
    res.send({"message": "Welcome!"});
});

welcomeRouter.get("/:name", (req: Request, res: Response) => {
    let { name } = req.params;

    res.send(`Hello, ${name}!`);
});

router.get("/", (req: Request, res: Response) => {
    res.send({"message":"Hello, World!"});
});

app.use("/", router);
app.use("/welcome", welcomeRouter);


app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}/`);
});

项目2

./ app.ts

import { Router, Request, Response } from "express";

const router: Router = Router();

router.get("/", (req: Request, res: Response) => {
    res.send({"message": "Welcome!"});
});

router.get("/:name", (req: Request, res: Response) => {
    let { name } = req.params;

    res.send(`Hello, ${name}!`);
});

export default router;

./ server.ts

import express from "express";
import { Router, Request, Response } from "express";

import welcomeRouter from "./app";

const app: express.Application = express();
const port: any = process.env.PORT || 3000;

const router: Router = Router();

app.use("/welcome", welcomeRouter);

router.get("/", (req: Request, res: Response) => {
    res.send({"message":"Hello, World!"});
});

app.use("/", router);
app.use("/welcome", welcomeRouter);

app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}/`);
});

1 个答案:

答案 0 :(得分:0)

你&#34; mount&#34;的顺序或public class ExampleController : Controller { [ChildActionOnly] private MyContainer InitialiseContainer() { MyContainer containter = new MyContainer(); containter.Header = new MyHeader(1, "Header Name"); containter.Details.Add(new MyDetail(1, 1, "Detail 1 Name", 100)); containter.Details.Add(new MyDetail(1, 2, "Detail 2 Name", 200)); return containter; } [HttpGet] public ActionResult Host() { //ViewBag.xxSelectedItem = "Detail Name 4"; Session["isAjaxCall"] = false; MyContainer container = InitialiseContainer(); ViewBag.Names = NamesLookup(null); return View(container); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Host(MyContainer container, string actionPerformed) { if (actionPerformed == "Save All") { //return RedirectToAction("xxx"); } if (actionPerformed == "Reload Detail") { if ((bool)Session["isAjaxCall"] == true) { ViewBag.DetailIndex = 0; ViewBag.Names = NamesLookup(null); NewModelContainer = (MyContainer)Session["MyContainer"]; return PartialView("Detail", NewModelContainer); } else { //this action runs if , from the ajax code we reference the Div(s) set by the parent view "Details" container = setsomeValues(container); ViewBag.DetailIndex = 0; ViewBag.Names = NamesLookup(null); return View(container); } } ViewBag.Names = NamesLookup(null); return View(container); } `public PartialViewResult GetAjaxPostBackData_OnlyTextBox(string ajaxDetailModelData, string index) { Session["isAjaxCall"] = true; int i = 0; int.TryParse(index, out i); ViewBag.DetailIndex = i; //get the items to populate the dropdown List with ViewBag.Names = NamesLookup(null); //get an instance of the Model (Container), either from session (with changed and persisted values in it, or Cleanly re-initialized) MyContainer NewModelContainer = InitialiseContainer(); NewModelContainer = UnpackAjaxdetailModelData(ajaxDetailModelData,index); //arb Test ..change the HTML Input NewModelContainer.Details[i].SomeNumber = 777; Session["NewModelContainer"] = NewModelContainer; //return just the partial view as indexed, which's btnXXX_index was clicked return PartialView("Detail", NewModelContainer); } [ChildActionOnly] private SelectList NamesLookup(object selectedObject) { List<MyName> names = new List<MyName>(); names.Add(new MyName(1, "Detail Name 1")); names.Add(new MyName(2, "Detail Name 2")); names.Add(new MyName(3, "Detail Name 3")); names.Add(new MyName(4, "Detail Name 4")); names.Add(new MyName(5, "Detail Name 5")); return new SelectList(names, "Name", "Name", selectedObject); } } 每个路由器都很重要。此外,为了与您安装它们的顺序一致,路径也很重要。将它们视为stack

所以对于第一个你有:

  1. app.use - &gt; /welcome
  2. welcomeRouter - &gt; /
  3. 因此当您执行router时,GET http://localhost:3000/welcome/hi将处理请求,因为它是堆栈中第一个与路径welcomeRouter匹配的请求。

    只做/welcome会产生GET http://localhost:3000/welcome,对吗?然后最后做{"message": "Welcome!"}收益:GET http://localhost:3000/welcome/hi

    对于第二个你有:

    1. Hello hi - &gt; /(我猜这个路由器指的是你在router中定义的路由器)
    2. app.ts - &gt; /welcome
    3. welcomeRouter导出app.ts对象的位置,您的路由定义为router

      这将处理任何事情:/:name。这意味着它还将处理/*,其中/welcome成为welcome参数。

      name移到welcomeRouter 之上应使其像项目1一样工作。