如何从app.js传递变量到routes/index.js?

18

我正在使用shrinkroute https://npmjs.org/package/shrinkroute 在nodejs中创建链接。但是,我收到了500错误ReferenceError:shrinkr未定义。

如何将shrinkroute传递给routes / index.js?有没有更好的方法通过传递查询字符串参数来创建URL?

//app.js
var app = express();

var shrinkr = shrinkroute( app, {
    "user": {
        path: "/user/:id?",
        get: routes.showOrListUsers
    }
});
//url method works in app.js    
var url = shrinkr.url( "user", { id: 5, page:40, type:'a' } );
console.log(url);

app.use( shrinkr.middleware );

//routes/index.js
exports.showOrListUsers = function(req, res, next) {                       
    console.log(req.params); 
    //shrinkr errors out in index.js                                      
    var url2 = shrinkr.url( "users", {name: "foo"});                       
    console.log(url2);                                                                         
}      
4个回答

39

解决方案之一是使用app.setshrinkr存储在你的应用程序对象中:

// app.js
...
app.set('shrinkr', shrinkr);
...
routes/index.js中,你可以通过req.appres.app对象进行访问。
exports.showOrListUsers = function(req, res, next) {
  var shrinkr = req.app.get('shrinkr');
  ...
};

使用app.locals设置应用程序本地变量会更符合惯用语。 - Yan Foto
1
@YanFoto 是的,那是另一个选项。使用 app.locals 的一个(轻微的)缺点是它会暴露给模板。 - robertklep
如果在 routes/index.js 中有很多处理程序,那该怎么办?你需要在每个函数中复制 var shrinkr = req.app.get('shrinkr'); 吗? - Avishay28
@Avishay28 请查看这个答案,特别是“使用中间件”部分。 - robertklep

12

来晚了,但以下代码也可以:

app.js

var my_var = 'your variable';

var route = require('./routes/index')(my_var);
app.get('/', route);

与此同时,在 route.js

var express = require('express')
,   router = express.Router()

// Router functions here, as normal; each of these
// run only on requests to the server

router.get('/', function (req, res, next) {
    res.status(200).end('Howdy');
});


module.exports = function(my_var){

    // do as you wish
    // this runs in background, not on each
    // request

    return router;
}

谢谢!这真的帮了我很多! - naveed
1
我本以为这对我有用,但到目前为止没有成功。你能详细说明一下这个答案吗?重点可能在于变量如何传递?作用域问题?这应该有效的情况?或者可能不起作用的情况?谢谢。 - tim.rohrer
这对我有帮助。 - nickang

1

有两种简单的方法可以实现您想要的:

1. 从您的路由中访问shrinkroute实例

就这么简单。在设置Shrinkroute之后,不需要任何其他操作。

exports.showOrListUsers = function(req, res, next) {
  var shrinkr = req.app.shrinkroute;
  console.log( "Route: " + req.route.name ); // ta-da, made available by Shrinkroute
  // do your URL buildings
};

2. 使用中间件

如果您不想使用 Shrinkroute 的非 URL 构建方法,可以使用中间件,在您的路由和模板中(通过 locals)提供一些帮助程序:

// app.js
app.use( shrinkr.middleware );

// routes/index.js
exports.showOrListUsers = function(req, res, next) {
  console.log( "Route: " + req.route.name ); // ta-da, made available by Shrinkroute

  req.buildUrl( "users", { name: "foo" } );
  // or, if you want the full url with the scheme and host...
  req.buildFullUrl( "users", { name: "foo" } );
};

也许你也希望在模版中使用它们?
// templates/index.jade
a( href=url( "users", { name: "foo" } ) ) Foo profile
a( href=fullUrl( "users", { name: "foo" } ) ) Foo profile

这种方法的优点是您无法直接访问路由中的路由设置器。
免责声明:我是Shrinkroute的作者。

1
+1 对于“使用中间件”,我应该更好地阅读文档 :) - robertklep
shrinkroute 中间件不起作用。我收到了 TypeError: Object #<IncomingMessage> 没有 'buildUrl' 方法的错误。 - Vlad Vinnikov
@VladVinnikov 这里有测试 来确保一切正常。如果您需要进一步帮助调试问题,请提交一个错误报告 - gustavohenke
@VladVinnikov 在版本0.3.1中,这样的问题将不会再出现。 - gustavohenke

0

你应该导入它。将以下行添加到代码的开头

  var shrinkroute = require('shrinkroute');

谢谢您的建议,但是没有帮助。index.js看不到shrinkr变量。 - Vlad Vinnikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接