【问题标题】:Get Id for item in EJS template and inject into service获取 EJS 模板中项目的 ID 并注入服务
【发布时间】:2015-03-15 03:02:34
【问题描述】:

我正在尝试弄清楚如何将 Id 传递给我的 PlayerDetailController,然后在我的服务中使用它。

我的主要app.js 中有以下路线:

var players = require('./routes/players');
app.use('/players', players);

我在players 路由 (routes/players.js) 中有以下路由:

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

/* GET /players listing. */
router.get('/', function(req, res, next) {
    res.render('players', { title: 'Players', action: 'list'});
});

/* GET /player details. */
router.get('/:id', function(req, res, next) {
    res.render('players', { title: 'Player Details', action: 'details'});
});

module.exports = router;

我的主要players.ejs 模板中的以下内容:

<!-- other layout elements -->
<% if (action === 'details') { %>
    <% include partials/players/details %>
<% } else if (action === 'update') { %>
    <% include partials/players/update %>
<% } else if (action === 'remove') { %>
    <% include partials/players/remove %>
<% } else { %>
    <% include partials/players/list %>
<% } %>
<!-- other layout elements -->

还有我的deatils.ejs部分:

<div ng-controller="PlayerDetailsController">
    <div class="playerDetails">
        <p>
            <strong>{{ player.name}} - {{ player.position }} - {{ player.team }}</strong><br/>
            Touchdowns: {{ player.touchdowns }}<br/>
            Yards: {{ player.yards }}
        </p>
    </div>
</div>

还有我的 PlayerDetiails 服务:

// PlayerDetails Service
app.factory('PlayerDetails', ['$http', function($http){
    // below is where I'm trying to inject the Id
    return $http.get('/api/player/:id');
}]);

但我不知道如何将路线中显示的 ID(例如 http://localhost:3000/players/550130d32f3345bc065f2ecf)传递到我的控制器中,以便我的控制器调用并接收正确的玩家数据。我该怎么做?我想我可以在res.render 调用中添加一个id 属性,但我不确定我会在EJS 模板中用它做什么。任何帮助将不胜感激!

【问题讨论】:

    标签: angularjs node.js express ejs


    【解决方案1】:

    将 id 传递给您的模板:

    router.get('/:id', function(req, res, next) {
        res.render('players', { title: 'Player Details', action: 'details', id: req.params.id});
    });
    

    ng-init 接收到 id:

    <div ng-controller="PlayerDetailsController" ng-init="id = <%= id %>">
    

    PlayerDetails 服务:

    app.service('PlayerDetails', ['$http', function($http){
        return {
             get: function(id) {
               return $http({
                url: '/api/player/:id',
                params: {id: id},
                method: 'GET'
               });
             }
        };
    }]);
    

    PlayerDetailsController 中的某处:

    // id is from ng-init
    PlayerDetails.get($scope.id).success(function(player) {
       $scope.player = player;
    }).error(function(error) {
       console.error(error);
    });
    

    【讨论】:

    • 由于我在单独的 .ejs 部分中有 ng-controller 并且我是 includeing 它,我认为我无法将 id 放入 ng-init 中。有没有办法将 id 传递给 ejs 部分?
    • 我注意到有一个新版本的 EJS (v2+) 能够将参数传递给包含 (github.com/mde/ejs#includes)。现在我在ng-init 中有一个ID。
    • 另外,由于我返回了一个只有 get() 函数的对象,因此我无法再访问 PlayerDetailsController 中的 .success().error() 回调。我的 js 控制台声称“未定义 (.success()) 不是函数”
    • @FillipPeyton 对,所以你已经调用了 get() 方法。 PlayerDetails.get($scope.id).success(function(player) { console.log(player) });
    • 有道理。所以现在我收到了这个语法错误:docs.angularjs.org/error/$parse/…
    【解决方案2】:

    传递给路由的 ID 将在 req.params.id 中可用。您可以使用 ID 从数据库中检索播放器并将对象传递给视图。

    类似这样的东西,使用 Mongoose ODM。如果您使用的是另一个数据库/ODM/ORM,代码会有所不同,但思路是一样的:

    /* GET /player details. */
    router.get('/:id', function(req, res, next) {
        Player.find({ _id: req.params.id }, function(err, player) {
            if(err) return next(err);
            res.render('players', { title: 'Player Details', action: 'details', player: player });
        });
    });
    

    然后您将可以通过player 属性访问播放器文档。

    如果你想创建一个以 JSON 格式返回所有玩家数据的 API,你可以这样做:

    /* GET /api/player/:id */
    router.get('/:id', function(req, res, next) {
        Player.find({ _id: req.params.id }, function(err, player) {
            if(err) return next(err);
            res.json(player);
        });
    });
    

    【讨论】:

    • 这很接近。我正在使用 Mongoose DB,但我不能将req.params.id 也传递给res.render() 参数吗?不过,我不确定将参数传递给res.render() 后如何处理它。
    • 是的,您可以通过res.render() 将id 直接传递给视图。但是你会用它做什么呢?从视图中查询数据库不是一个很好的做法。如果视图接收到已经从数据库中获取的玩家数据会更好。
    • 这也是我困惑的地方。最终,我希望能够将 id 注入我的PlayerDetails 服务(只是对上面的原始问题进行了一些更改)
    • 您的服务正在调用/api/player/:id,但您的视图在/player/:id,对吗?如果是这种情况,您应该在 api 路由 (/api/player/:id) 中返回从数据库返回的整个文档。这样,您将获得 JSON 格式的有关播放器的所有信息。然后你可以在你的 Angular 应用程序中使用来自这个 http 请求的数据。用一个例子更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 2020-03-09
    • 2013-12-06
    • 1970-01-01
    • 2020-12-24
    相关资源
    最近更新 更多