【问题标题】:Node.js does not recognize model definitions across multiple filesNode.js 无法跨多个文件识别模型定义
【发布时间】:2015-02-19 08:53:41
【问题描述】:

我的 app.js requires 这些文件:

var fs = require('fs');
var http = require('http');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');

// Custom Modules
fs.readdirSync(__dirname + '/models').forEach(function(filename) {
    if (filename.indexOf('.js')) require(__dirname + '/models/' + filename)
});

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

所以,如您所见,首先是 mongoose,其次是 /models/ 中的模型文件,最后是 /routes/ 中的路由文件。在其中一个模型文件posts.js 中,我定义了这个:

var Post = mongoose.model('posts', postsSchema);

由于需要顺序,我认为 Post 可以从 /models/ 要求的任何地方下方访问。但是,从/routes/index.js 中访问Post 会引发错误,指出Post 未定义:

var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');

router.get('/submit/', function (req, res) {
    var submission = new Post({
        // ...
    });
});

我可以从/models/posts.js 中访问Post,但不能从其他任何地方访问。我的错误是什么?提前致谢。

【问题讨论】:

  • 要使用变量 Post 您需要先分配变量。像这样:var Post = require('path/to/your/models/post') 不过,要将其烘焙到您的 forEach 中,您还需要做更多的工作。考虑您的自动化是否真的有必要。您可能会发现手动执行它会使其更具可读性。
  • 方法是在你的其他文件中require('mongoose'),然后通过var Post = mongoose.model('Post')访问Post
  • 谢谢!我发现我还必须在 /modules/posts.js 的末尾附加 module.exports = Post; 以便模型传递。我想知道,如果我必须在我的路由文件中单独要求这些 .js 文件,为什么我还要在 app.js 中要求这些文件?这是正确的做法吗?
  • 你不必像那样导出它,只要你使用 mongoose 从模式中创建模型,任何需要相同 mongoose 副本的东西都可以使用model('modelName') 方法。
  • 看看这个boilerplate project你可以感受一下这样做的一种方式

标签: node.js mongoose


【解决方案1】:

每个模块都存在于自己的命名空间中,因此有一个常规的顶级变量定义,例如:

var Post = mongoose.model('posts', postsSchema);

不是全局可访问的变量。该变量只能在该模块内访问。

要扩大该变量的使用范围,您有多种选择:

  1. 您可以导出变量,以便require() 您所在的模块可以直接从导出中访问模型。

  2. 您可以导出一个方法,该方法允许 require() 您的模型的任何人随后调用以获取该变量。我将此称为导出的“拉”模型,其中其他模块从您那里“拉”一个值。

  3. 您可以调用其他模块中的方法并将变量发送给它们。我将其称为导出的“推”模型,因为您将值发送到另一个模块。

  4. 您可以使用 nodejs global 符号显式声明全局。 global.Post = mongoose.model('posts', postsSchema);。并且,代码中的其他地方也可以以同样的方式引用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 2018-12-15
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    相关资源
    最近更新 更多