Express.js是否支持命名路由?

15

基本路由如下:

app.get('/', function(req, res){
  res.send('hello world');
});

是否可以给这个路由命名,并在任何模板中都可以使用它,以便像这样使用:

app.get('/', name="index", function(req, res){
  res.send('hello world');
});

Go to site <a href="{% url index %}">index page</a>.

灵感来自 Django :)


1
你可能想要看一下以下几点:express-resource 以保持命名的一致性,以及查看 locomotive 如何实现 urlFor - David Weldon
如果您回到这个问题,请看一下Shrinkroute。它正在积极维护,并且与Express 3兼容。 - gustavohenke
1
+1 给你,因为你提到了 Django 的 {% url %} 模板标签 :) - nik_m
6个回答

13

没有现成的机制可以做到这一点。不过,您可以像Django那样模仿它的风格:定义一个urls.js文件,其中包含URL数组。首先从以下内容开始:

myviews.js

exports.Index = function( req, res, next ) {
    res.send( "hello world!" );
};

urls.js

var MyViews = require( "mywviews.js" );

module.exports = [
    { name : "index", pattern : "/", view : MyViews.Index }
]

现在在 app.js(或主文件)中,您需要将 URL 绑定到 Express。例如:

app.js

var urls = require( "urls.js" );

for ( var i = 0, l = urls.length; i < l; i++ ) {
    var url = urls[ i ];
    app.all( url.pattern, url.view );
};

现在你可以定义自定义助手(Express 3.0风格):

var urls = require( "urls.js" ), l = urls.length;
app.locals.url = function( name ) {
    for ( var i = 0; i < l; i++ ) {
        var url = urls[ i ];
        if ( url.name === name ) {
            return url.pattern;
        }
    };
};

你可以轻松地在模板中使用它。现在问题是,它没有像Django中那样提供花哨的URL创建机制(在那里可以将附加参数传递给url)。另一方面,你可以修改url函数并进行扩展。我不想在这里讨论所有细节,但以下是一个示例,说明如何使用正则表达式(你应该能够将这些思路结合起来):

Express JS反向URL路由(Django风格)

请注意,我发布了这个问题,所以我之前也遇到了同样的问题。:D


9
这句话的意思是,通过这种方法,你可以在不改变模板中所有字符串的情况下更改你的URL。硬编码URL是不好的。 - Aleksandrenko
怪异的: 谢谢,当我开始编写我的应用程序时,我会将其制作成一个组件 :) 以便更容易地使用。我不确定如何构建我的应用程序,但可以使用Django的应用程序结构来创建一些东西。 - Aleksandrenko

4
我发现express-reverse很好地解决了这个问题。

https://github.com/dizlexik/express-reverse

它扩充了标准路由,允许你将路由名称作为第一个参数传递。
app.get('test', '/hello/:x', function(req, res, next) {
    res.end('hello ' + req.params.x);
});

让您通过名称在模板内构建URL
<a href="<%= url('test', { x: 'world' }) %>">Test</a>

让您通过名称重定向到一个URL
app.get('/test-redirect', function(req, res, next) {
    res.redirectToRoute('test', { x: 'world' });
});

1
这个问题在于它无法使用 express.Router(),因此您无法使用 router.route('/url').get().post().put(),这是非常方便的。 - Andrey Popov

1

我在这里没有看到的另一个选项是将路由函数提取出来,并使用函数名称。如果你所要做的只是编写自说明代码。

function updateToDo(req, res, next) { /*do router stuff*/};
router.put('/', updateToDo);

0

我认为这就是你要找的内容:命名路由

示例代码:

var express = require('express');
var app = express();

var Router = require('named-routes');
var router = new Router();
router.extendExpress(app);
router.registerAppHelpers(app);

app.get('/admin/user/:id', 'admin.user.edit', function(req, res, next){
    // for POST, PUT, DELETE, etc. replace 'get' with 'post', 'put', 'delete', etc.

    //... implementation

    // the names can also be accessed here:
    var url = app.namedRoutes.build('admin.user.edit', {id: 2}); // /admin/user/2

    // the name of the current route can be found at req.route.name
});

app.listen(3000);

正如您所看到的,您可以将路由命名为admin.user.edit并在视图中访问它


0

我遇到了同样的问题,决定制作一个库来帮助自己。

除了不硬编码你的路由,它还允许我构建导航组件,比如面包屑,并且我可以在服务器端使用express或者客户端使用Backbone或其他任何框架。

https://github.com/hrajchert/express-shared-routes


有趣 :) 你如何在jade中使用命名路由?例如,在表单中:form(action='???' method='post' role='form' class='form-horizontal') - Pathros
我最终创建了自己的... 4年前:D 哇,时间过得真快。 - Aleksandrenko

0

请查看这个Gist

var env="http://localhost:3000/"
var route='users/:id/profile/'
var routes=[
  {
    'name':'profile',
    'path':'users/:id/:profile/'

  }
]


function RouteName(route,arg){
  let targetRoute = routes.find(e=>e.name==route).path
  for(var key in arg){

  targetRoute=targetRoute.replace(`:${key}`,arg[key])
  //console.log(targetRoute)

}
return targetRoute

}

console.log(env+RouteName('profile',{'id':3,'profile':'loaiabdalslam'}))

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