我知道Express并不是开箱即用的MVC框架,但是我试图将其设置为一个。

我在PHP中使用了其他类似的框架,例如Laravel,在其中的路由中,您可以使用类似

Route::get('user/profile', 'UserController@showProfile');


它将运行UserController类的showProfile方法中的所有代码,
所以我的问题是,使用Express如何实现相同或相似的目的?

我正在使用节点5并在ECMAScript 6中编写代码。

目前,我有一个要用作控制器的类和一个要返回数据的方法,当用户导航到路由但还没有弄清楚如何发送数据时,我可以将数据记录到控制台作为回应。

最佳答案

如果深入研究the documentation,您会发现所引用的“控制器方法”必须符合特定的签名。即,它们接收(至少)请求和响应表示。

如果您已经创建了router,那么这将与您发布的PHP大致相同:

router.get('user/profile', userController.showProfile)


您的showProfile“方法”需要具有以下签名:

const userController = {
  showProfile(req, res) { /*...*/}
}


我将“方法”用引号引起来,因为除非您明确将其绑定到控制器对象,否则express不会将其称为方法。我们在这里将其作为未绑定函数传递。如果要使用它作为方法(以this的身份访问控制器),请将userController.showProfile.bind(userController)传递给router.get†。

但是现在,让我们坚持使用req处理程序的那些resshowProfile参数(这是正确的名称)。 req代表HTTP请求,您可以从中获取标头,请求有效负载和其他内容。 res是将发送的HTTP响应。因此,您可以使用它来设置HTTP状态代码,发送正文数据等。

出于说明目的,假设您可以通过调用userController.getProfile(id)同步获取用户配置文件。并假定通过某种机制,在userId uest上设置了一个属性req,它是当前经过身份验证的用户的ID。

const userController = {
  showProfile(req, res) {
    // We call some code to get what we want to send back
    const profile = userController.getProfile(req.userId)
    // We send it in the response as JSON
    res.send(profile)
  }
}


res.json将对配置文件进行JSON.stringify并将其作为响应负载发送。

您问如何设置req.userId?好吧,这只是一个例子,但是您可以通过使用中间件来获得类似的结果。中间件只是一个处理某事的处理程序,然后让其他处理程序继续处理该请求。但是同样,从文档中可以读取很多内容。

†但是通常没有必要,因为控制器往往是单例。您只需执行userController.otherProperty即可访问其属性。当然,您甚至不需要将处理程序定义为控制器对象的方法,它可以是独立存在的函数。

09-27 01:00