Node.JS - 在模块中使用原型

Joh*_*ink 4 javascript prototype commonjs node.js

所以我在节点中编写了一大堆特定于供应商的文件,这些文件都有类似的控制器模式,因此我将它们剪切掉并放入一个公共文件是有意义的.

你可以在这里看到我的通用控制器文件:https://gist.github.com/081a04073656bf28f46b

现在当我在我的多个模块中使用它们时,每个连续加载的模块都会覆盖第一个模块.这是因为文件只需要一次并在加载时动态传递给每个模块(这允许我添加额外的模块,这些模块能够添加自己的路由,例如).你可以在这里看到一个示例模块:https://gist.github.com/2382bf93298e0fc58599

你可以在第53行看到我已经意识到我们每次都需要创建一个单独的实例,所以我试图通过将standardControllers对象复制到一个新对象,然后初始化新对象来创建一个新实例.这对代码没有任何影响,代码的行为方式完全相同.

有什么想法吗?我有点干这个!

tim*_*ley 12

我要做的第一件事是尝试通过调用单一责任原则等方法使事情更简单并减少耦合. http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html

将这些Schema放入自己的文件中,例如

models/client.js
models/assistant.js
models/contact.js
Run Code Online (Sandbox Code Playgroud)

我还发现嵌入式文档+ mongoose通常是PITA.我可能会将所有这些推广到顶级文档.

您不需要将对象的键括在引号中.

routes = {
   list: function() {} // no quotes is aok
}
Run Code Online (Sandbox Code Playgroud)

典型REST应用程序中的"列表"也称为"索引".无论如何.

好的,我会以不同的方式打破这个.由于你需要中间件中的index.js文件中的东西,它们会变得紧密耦合,这很糟糕.事实上,我认为我会改写这一切,所以它更整洁.抱歉.

我可能会用快速资源控制器https://github.com/visionmedia/express-resource(由express的作者建立)替换你的'中间件'文件 .对于安静的控制器来说,这是一个很好的框架,例如您正在构建的内容.自动装载机非常好用.

您可能还想看看:http://mcavage.github.com/node-restify/这是新的,我还没试过,但我听说过好东西.

由于您正在构建的基本上是一个自动的mongoose-crud系统,可选的覆盖,我将创建一个快速资源控制器作为您的基础

/controllers/base_controller.js
Run Code Online (Sandbox Code Playgroud)

它可能看起来像

var BaseController = function() {} // BaseController constructor

BaseController.prototype.index = function() {
   // copy from your middleware
}
BaseController.prototype.show = function() {
   // copy from your middleware
}
BaseController.prototype.create = function() {
   // copy from your middleware
}
// etc

module.exports = BaseController
Run Code Online (Sandbox Code Playgroud)

然后我会做类似的事情:

/controllers/some_resource_controller.js
Run Code Online (Sandbox Code Playgroud)

这可能看起来像:

var BaseController = require('./base_controller')
var NewResourceController = function() {
    // Apply BaseController constructor (i.e. call super())
    BaseController.apply(this, arguments) 
}

NewResourceController.prototype = new Base()

NewResourceController.prototype.create = function() {
    // custom create method goes here
}



module.exports = NewResourceController
Run Code Online (Sandbox Code Playgroud)

然后使用它,你可以做:

var user = app.resource(myResourceName, new ResourceController());
Run Code Online (Sandbox Code Playgroud)

...在一些循环中,它设置myResourceName为你想要设置的任何东西.

这里有一些链接供您阅读:

而且,听起来你不是在写测试.写测试.

  • 哇.一个地狱的答案.我将不得不逐一完成这件事.感谢您抽出宝贵的时间!我喜欢stackoverflow. (2认同)
  • 在`NewResourceController`的控制器中,您应该编写类似`Base.call(this)`的东西来应用在子类的Base-Constructor中执行的操作.(例如,创建特权方法) (2认同)
  • 我很确定这一行:`NewResourceController.prototype = new Base()`应该在*之前定义`NewResourceController.prototype.create` (2认同)