Angular - $ routeParams.itemID用于加载domain.com/:itemID ALMOST WORKING?

时间:2014-04-07 20:42:20

标签: javascript node.js angularjs express mongoose

我希望通过在变量名称

之前使用冒号来在路径中包含参数
// dynamic pages for each ITEM, once selected
// from $routeParams.itemID in ItemCtrl
.when('/:itemID', {
        templateUrl: 'views/item.html',
        controller: 'ItemController'
})

单击div框时,Angular应路由到特定项

<div class="itemBox" ng-click="getItem(item._id)">

现在,对node / express API的调用似乎正在运行

[16:36:18.108] GET http://localhost:8080/api/items/534240001d3066cc11000002 [HTTP/1.1 304 Not Modified 4ms]

但是此错误会在控制台中记录:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
    ...
    at Promise.<anonymous> (/Users/Username/Downloads/project/v19/app/routes.js:41:8)
    ...

routes.js中的第41行(41:8?)是res.json(item);

// load the item model
var Item = require('./models/item');

// get One item
app.get('/api/items/:item_id', function(req, res) {

        // use mongoose to get the one item from the database
        Item.findById({
                _id : req.params.item_id
        },

        function(err, item) {

                // if there is an error retrieving, send the error. nothing after res.send(err) will execute
                if (err)
                        res.send(err)

                res.json(item); // return the item in JSON format
        });
});

虽然看起来问题可能在Controller中,因为所有其他API调用都有效..所以我尝试将$ routeParams传递到所有地方!

angular.module('ItemCtrl', [])

// inject the Item service.factory into our controller
.controller('ItemController', function($scope, $routeParams, $http, Items, isEmptyObjectFilter) {

        // get an Item after clicking it
        $scope.getItem = function(id, $routeParams) {
                Items.getOne(id, $routeParams)
                        // if successful getByID, call our function to get the Item data
                        .success(function(data, $routeParams) {
                                // assign our Item
                                $scope.item = data;
                                // for use with a parameter in appRoutes.js using itemID as the variable
                                $scope.itemID = $routeParams.itemID;
                        })
                        .error(function(data) {
                                console.log('Error: ' + data);
                        });
        };
});

或者也许这是服务?这是否需要传递$ routeParams作为函数(id,$ routeParams)

angular.module('ItemService', [])

// super simple service
// each function returns a promise object 
.factory('Items', function($http) {
        return {
                get : function() {
                        return $http.get('/api/items');
                },
                getOne : function(id) {
                        return $http.get('/api/items/' + id);
                },
                create : function(itemData) {
                        return $http.post('/api/items', itemData);
                },
                delete : function(id) {
                        return $http.delete('/api/items/' + id);
                }
        }
});

真的很感激一些帮助调试这个..谢谢

2 个答案:

答案 0 :(得分:1)

该消息是因为您收到错误并执行res.send()方法,之后您有res.json(),express正在尝试响应两次。

尝试更改:

if (err)
  res.send(err)

要:

if (err) {
  res.json({ error: err }); 
} else {
  var object = item.toObject();
  res.json(object);
}

角度资源示例:

angular.module('ItemService')
.factory('Items', ['$resource', function($resource) {
    return $resource('/api/items/:itemID', {
        itemID: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}]);

现在您可以在控制器中执行此操作:

// Find
Items.get({
  itemID: $routeParams.itemID
}, function(item) {
  $scope.item = item;
});

// Update
$scope.item.name = 'New name';
$scope.item.$update();

// Remove
$scope.item.$remove();

答案 1 :(得分:1)

看起来您正确地获取数据。问题是您希望在成功获得API调用后更改路由吗?

$ routeParams不会为您改变路线。这只是获取数据。使用$ location更改路线。

.controller('ItemController', function($scope, $routeParams, $location, $http, Items, isEmptyObjectFilter) {
$scope.getItem = function(id) {
    Items.getOne(id)
        .success(function(data) {
              $scope.item = data;
              $scope.itemID = $routeParams.itemID;

              // redirect
              $location.path('/' + $routeParams.itemID);
        });
});
});

由于您的所有数据似乎已准备就绪,您只需要Angular重定向到该路线即可。 $ location应该是最佳选择。