【问题标题】:Accessing Mongoose schema object from Express 3 routes从 Express 3 路由访问 Mongoose 模式对象
【发布时间】:2014-10-12 04:20:18
【问题描述】:

如何将 app.js 中设置的 MongooseSchema 对象暴露给路由?

我在尝试使用 routes/index.jsapp.js 中设置的变量时收到此错误。我使用 node 才几个月,所以我不确定我在这里缺少什么。

请注意我使用的是 Express v3.3.4

500 ReferenceError: ProfileSchema is not defined

在我的 app.js 文件中,我有:

var express = require('express')
  , util = require('util')
  , Promise = require('bluebird')
  , crypto = require('crypto')
  , routes = require('./routes')
  , http = require('http')
  , path = require('path');

var ProfileSchema = require('./models/schemas').ProfileSchema;

/*** ..... ***/

app.get('/user/home', routes.user_home);

在我的 /routes/index.js 我有:

exports.user_home = function(req, res){
    //foo
}

我想在 user_home 路由中执行此操作:

ProfileSchema.find({ users: 'joeblow' }, function (err, docs) {});

但是会抛出 ReferenceError,因为 ProfileSchema 无法访问路由。

注意:我可以很好地使用 app.js 中的 ProfileSchema.find()。

【问题讨论】:

    标签: node.js express routes mongoose


    【解决方案1】:

    那是因为您的ProfileSchema 仅在 app.js 中定义,但 app.js/routes/index.js 确实如此不共享相同的范围

    起初这可能会让人感到困惑,因为它与客户端 JavaScript 不同,但您应该花几分钟时间仔细阅读 Node.js docs regarding globals。 引用文档,

    在浏览器中,顶级作用域是全局作用域。这意味着在浏览器中,如果您处于全局范围 var 中,则某些内容将定义一个全局变量。在 Node 中,这是不同的。顶级范围不是全局范围; var 某个 Node 模块中的某些内容将是该模块本地的

    要解决您的问题,您有两种解决方案

    • 您可以直接要求您的ProfileSchema /routes/index.js

      var ProfileSchema = require('./models/schemas').ProfileSchema;
      
      exports.user_home = function(req, res){
          //ProfileSchema is defined ! Hurray !
      }
      
    • 或者,如果您仍想在 app.js 中要求 ProfileSchema,您 需要做一些称为依赖注入的事情, 表示您需要通过ProfileSchema 的复杂词 /routes/index.js 的变量。一种方法是导出一个 /routes/index.js 中的函数,它将ProfileSchema 作为 范围。因此,您需要将代码更改为:

      exports.user_home = function(ProfileSchema){
         return function(req, res){
          //ProfileSchema is defined ! Hurray !
        }
      }
      

      您可以像这样在 app.js 中传递参数:

      var ProfileSchema = require('./models/schemas').ProfileSchema;
      app.get('/user/home', routes.user_home(ProfileSchema));
      

    【讨论】:

    • 您好,感谢您的回复。我不能像这样将变量放在 routes/index 中:var ProfileSchema = module.exports.ProfileSchema = require('./models/schemas').ProfileSchema; 以将其传递回 app.js 吗?这样他们都可以访问它?
    • @taco 是的,当然,他们都可以访问它。您可以在两个文件中都需要您的模块在一个文件中并将其导出到另一个文件反之。这完全取决于你。只需尝试尽可能地遵守您在整个应用程序中选择的规则(例如,在需要时需要模块并避免依赖注入,或者只需要 app.js 中的模块并注入它们在您的控制器等...),这将为您省去一些麻烦。
    • 再次感谢沃尔多。我以前见过有人这样导出,但直到你解释了解决方案,这一切都没有点击。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 2019-07-10
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2018-02-28
    • 2015-04-15
    相关资源
    最近更新 更多