在root上快速命名占位符路由

时间:2014-08-10 11:18:19

标签: javascript node.js angularjs express

我正在构建一个MEAN应用程序,我有你想要的路由设置(/ login,/ profile,/ logout等)。我现在已经开始在我的应用程序中建立用户个人资料页面了,我希望可以从域的根目录访问用户个人资料,例如:www.domain.com/:username

我目前在route.js文件的末尾和我的catchall / wildcard路由之前定义了以下路由。

app.get('/:username', function (req, res) {
    var username = req.params.username;
        usersTable.findOne({ 'local.username': username }, function (err, user) {               
            if (err)
                return err;

            if (!user)
                res.redirect('/');

            res.render('public-profile.ejs', {
                user: user
            });
        });
});

app.all('/*', function (req, res, next) {
    if (req.user) {
        res.sendfile('views/dashboard.html'); // for angular routing
    } else {
        res.redirect('/login');
    }
});

目前看,Express / Angular之间存在一些干扰。如果我访问/ matthew这是一个用户名,然后尝试从URL栏加载/配置文件,Angular不会捕获此(/ *路由),而是加载默认('/')角度路由。

我担心的是我无法在Angular中创建/:用户名路由,因为该页面将如何知道要显示的用户数据?我是否必须创建一个API调用来读取给定的URL,然后在该数据库中查找具有该名称的用户? (看起来很笨重?)

我很擅长构建大型Web应用程序,因此对架构的建议会很棒。

1 个答案:

答案 0 :(得分:1)

您帖子中的代码仅配置服务器端路由,实际上与Angular路由无关。

Angular适用于单页面应用程序(SPA)。如果您想在客户端上使用AngularJS,您可能不希望从服务器提供页面,但返回数据,即您的路由仅用于API调用。

因此,在客户端,你应该有类似的东西:

myApp
.constant('MY_BACKEND_URL', 'http://www.domain.com')
.config(['$stateProvider', function ($stateProvider) { // client-side route config

  $stateProvider
    .state('userProfile',{
    url: '/:username',
    templateUrl: 'views/user-profile.html',
    controller: 'UserProfileCtrl',
    resolve: { // lets you resolve asynchronously before page is loaded.
      userData: ['$http', 'MY_BACKEND_URL', '$stateParams', '$state', function ($http, MY_BACKEND_URL, $stateParams, $state) {
        return $http
          .get(MY_BACKEND_URL + '/' + $stateParams.username)// returns a promise of the user data fetch from the API.
          .catch(function (err) {
            $state.go('dashboard');
          });
      }]
    }
  });

  $stateProvider.state('dashboard',{
    url: '/',
    template: 'views/dashboard.html',
    controller: 'DashboardCtrl'
  });
}]);

在服务器端:

// config route for API call to user resource 
app.get('/user/:username', function (req, res) {
  var username = req.params.username;
  usersTable.findOne({ 'local.username': username }, function (err, user) {
    if (err) {
      res.json(500, err);
    } else if (!user) {
      res.json(404, {reason: "No such username", username: username});
    } else {
      res.json(200, user);
    }
  });
});

根据经验,客户端(Angular)上的路由配置页面,而服务器端的路由配置您的API,即您调用以获取数据的端点。

顺便说一下,你应该从你的回调中删除return err;语句,因为没有必要从仅用于副作用的回调函数返回一个值。您可能希望用以下内容替换它:

if(err){
  res.json(500, err); // return internal server error response.
}