将别名查询字符串表示为参数
Express alias query strings as params
我正在用 node、express 和 jade 做一个项目。我想通过以下方式访问内容:
/Page/foo/bar
和
/Page?Foo=foo&Bar=bar
我希望顶部作为底部的别名。
这是我现在的解决方案:
server.js
// some stuff
app.get('/Page/:Foo/:Bar',function(req,res){
res.render('Page.jade', {Foo: req.params.Foo, Bar: req.params.Bar});
});
app.get('/Page',function(req,res){
res.render('Page.jade', {Foo: req.query.Foo, Bar: req.query.Bar});
});
// more stuff
Page.jade
doctype html
html
head
script var foo = "!{Foo}"; bar = "!{Bar}";
script(src="/Page.js")
// stuff
Page.js
// stuff with foo and bar, such as:
console.log(foo);
console.log(bar);
我不喜欢这个解决方案的一点是,它迫使我用 express 分别处理参数和查询(这几乎是重复的代码,但还不够接近以减少它),将它传递给 jade ,它将它存储在一个变量中,其唯一目的是让链接的 javascript 文件使用这些变量。
通常只使用查询字符串,我只需要在 Page.js 中触摸它。有没有办法设置 express 有效地将第一个 URL 解释为查询字符串,就像第二个 URL,这样 jade 文件就不必触及变量?
您可以自己设置对象属性并继续下一条路线等
app.use('/Page/:Foo/:Bar',function(req, res, next){
for (var key in req.params) {
req.query[key] = req.params[key];
}
next();
});
选项 1:如果你只是想减少代码冗余,也许你可以将你的控制器保存在一个外部文件中,这样你最终会得到一些东西像这样:
controllers/fooBarController.js
:
exports.fooBarQueryOrParams = function(req, res) {
res.render('Page.jade', {
Foo: req.params.Foo || req.query.Foo,
Bar: req.params.Bar || req.query.Bar
});
}
如果 undefined
无效,您还可以使用另一个 ||
运算符添加默认值。
server.js
:
var fooBarController = require('controllers/fooBarController');
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
选项 2: 同样的事情,但仅按其名称使用 res.locals
, so now there's no need to pass any object to Page.js
, all your views will see res.locals
属性,在本例中为 Foo
和 Bar
(不是 res.locals.Foo
和 res.locals.Bar
)。
controllers/fooBarController.js
:
exports.fooBarQueryOrParams = function(req, res) {
res.locals.Foo = req.params.Foo || req.query.Foo;
res.locals.Bar = req.params.Bar || req.query.Bar;
res.render('Page.jade');
}
server.js
:
var fooBarController = require('controllers/fooBarController');
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
选项 3: 总是暴露所有想法 res.locals
:
controllers/fooBarController.js
:
exports.fooBarQueryOrParams = function(req, res) {
res.render('Page.jade');
}
server.js
:
var fooBarController = require('controllers/fooBarController');
app.use(function(req, res, next) {
for (var key in req.params) res.locals[key] = req.params[key];
for (var key in req.query) res.locals[key] = req.query[key];
next();
});
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
我会选择第一个选项,因为我认为您真的不需要在所有视图中使用 Foo
和 Bar
,因此使用 res.locals
没有意义让他们了解您的所有观点,而不仅仅是真正需要他们的人。
我正在用 node、express 和 jade 做一个项目。我想通过以下方式访问内容:
/Page/foo/bar
和
/Page?Foo=foo&Bar=bar
我希望顶部作为底部的别名。
这是我现在的解决方案:
server.js
// some stuff
app.get('/Page/:Foo/:Bar',function(req,res){
res.render('Page.jade', {Foo: req.params.Foo, Bar: req.params.Bar});
});
app.get('/Page',function(req,res){
res.render('Page.jade', {Foo: req.query.Foo, Bar: req.query.Bar});
});
// more stuff
Page.jade
doctype html
html
head
script var foo = "!{Foo}"; bar = "!{Bar}";
script(src="/Page.js")
// stuff
Page.js
// stuff with foo and bar, such as:
console.log(foo);
console.log(bar);
我不喜欢这个解决方案的一点是,它迫使我用 express 分别处理参数和查询(这几乎是重复的代码,但还不够接近以减少它),将它传递给 jade ,它将它存储在一个变量中,其唯一目的是让链接的 javascript 文件使用这些变量。
通常只使用查询字符串,我只需要在 Page.js 中触摸它。有没有办法设置 express 有效地将第一个 URL 解释为查询字符串,就像第二个 URL,这样 jade 文件就不必触及变量?
您可以自己设置对象属性并继续下一条路线等
app.use('/Page/:Foo/:Bar',function(req, res, next){
for (var key in req.params) {
req.query[key] = req.params[key];
}
next();
});
选项 1:如果你只是想减少代码冗余,也许你可以将你的控制器保存在一个外部文件中,这样你最终会得到一些东西像这样:
controllers/fooBarController.js
:exports.fooBarQueryOrParams = function(req, res) { res.render('Page.jade', { Foo: req.params.Foo || req.query.Foo, Bar: req.params.Bar || req.query.Bar }); }
如果
undefined
无效,您还可以使用另一个||
运算符添加默认值。server.js
:var fooBarController = require('controllers/fooBarController'); app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams); app.get('/Page', fooBarController.fooBarQueryOrParams);
选项 2: 同样的事情,但仅按其名称使用
res.locals
, so now there's no need to pass any object toPage.js
, all your views will seeres.locals
属性,在本例中为Foo
和Bar
(不是res.locals.Foo
和res.locals.Bar
)。controllers/fooBarController.js
:exports.fooBarQueryOrParams = function(req, res) { res.locals.Foo = req.params.Foo || req.query.Foo; res.locals.Bar = req.params.Bar || req.query.Bar; res.render('Page.jade'); }
server.js
:var fooBarController = require('controllers/fooBarController'); app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams); app.get('/Page', fooBarController.fooBarQueryOrParams);
选项 3: 总是暴露所有想法
res.locals
:controllers/fooBarController.js
:exports.fooBarQueryOrParams = function(req, res) { res.render('Page.jade'); }
server.js
:var fooBarController = require('controllers/fooBarController'); app.use(function(req, res, next) { for (var key in req.params) res.locals[key] = req.params[key]; for (var key in req.query) res.locals[key] = req.query[key]; next(); }); app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams); app.get('/Page', fooBarController.fooBarQueryOrParams);
我会选择第一个选项,因为我认为您真的不需要在所有视图中使用 Foo
和 Bar
,因此使用 res.locals
没有意义让他们了解您的所有观点,而不仅仅是真正需要他们的人。