Angular 以数组为参数的资源更新方法

Angular Resource update method with an array as a parameter

我已经在谷歌上搜索了几个星期,但没有真正的解决办法。

我相信有人会把它标记为重复,但我不确定它是否真的是,也许我只是太具体了,不管怎样。

我正在构建的 node-webkit 应用程序中使用 angular。我有一个内置 express 的 api,我正在使用 MongoDB (@mongolab) 和 Mongoose 作为数据库。

只要所有数据类型都是简单的字符串和数字,我就可以正常工作。但我不得不重组数据以使用数组和复杂对象。重组数据后,我能够让 post API 调用正常工作,但我根本无法让 PUT 调用工作。

数据如下所示:

itemRoles 是一个数组,但我认为它会抛出我现在遇到的错误,所以我将它转换回字符串。

itemStats 导致了问题。 Angular 正在寻找一个对象,但 itemStats 是一个数组(我认为无论如何)。 itemStats 过去也是一个字符串,但在我看来,如果它是一个具有 key:value 对的对象数组,它更容易使用,这就是我更改它的原因。

请注意,我也是 MongoDB 的新手,第一次使用它。

{
  "_id": {
    "$oid": "55a10b9c7bb9ac5832d88bd8"
  },
  "itemRoles": "healer,dps",
  "itemRating": 192,
  "itemName": "Advanced Resolve Armoring 37",
  "itemClass": "consular",
  "itemLevel": 69,
  "itemStats": [
    {
        "name": "Endurance",
        "value": 104,
        "_id": {
            "$oid": "55a10b9c7bb9ac5832d88bda"
        }
    },
    {
        "name": "Willpower",
        "value": 124,
        "_id": {
            "$oid": "55a10b9c7bb9ac5832d88bd9"
        }
    }
  ],
  "__v": 0
}

猫鼬模式如下所示:

var mongoose     = require('mongoose');
var Schema       = mongoose.Schema;

//var stats = new Schema({
    //name: String,
    //value: Number
//});

var armoringSchema   = new Schema({
    itemType: String,
    itemClass: String,
    itemRoles: String,
    itemLevel: Number,
    itemName: String,
    itemRating: Number,
    itemStats: [{ name:String, value:Number}]
});

module.exports = mongoose.model('Armor', armoringSchema);

快递API路线:

/ on routes that end in /armors/:id
// ----------------------------------------------------
router.route('/armors/:id')
// get method omitted
// update the armoring with specified id (accessed at PUT http://localhost:8080/api/armors/:id)
.put(function(req, res) {

    // use our armor model to find the armor we want
    Armoring.findById({_id: req.params.id}, function(err, armor) {

        if (err) {
            return res.send(err);
        }

        for(prop in req.body) {
            armor[prop] = req.body[prop];
        }


        // save the armor
        armor.save(function(err) {
            if (err) {
                return res.send(err);
            }

            res.json({success:true, message: 'Armor updated!' });
        });

    });
})

资源工厂:

swtorGear.factory('armoringFactory', ['$resource', function ($resource) {
    return $resource('http://localhost:8080/api/armors/:id', {}, {
        update: { method: 'PUT', params: {id: '@_id'}},
        delete: { method: 'DELETE', headers: {'Content-type': 'application/json'}, params: {id: '@_id'}}
    });
}]);

编辑路线:

.when('/edit/armor/id/:id', {
        templateUrl: 'views/modelViews/newArmor.html',
        controller: 'editArmorCtrl',
        resolve: {
            armoring: ['$route', 'armoringFactory', function($route, armoringFactory){
                return armoringFactory.get({ id: $route.current.params.id}).$promise;
            }]
        }
    })

控制器(只是保存方法,控制器的第一部分用现有数据填充表单):

$scope.save = function(id) {
    $scope.armor.itemStats = [
        $scope.armor.stats1,
        $scope.armor.stats2
    ];

    $scope.armor.itemRoles = '';
    if($scope.armor.role.tank) {
        $scope.armor.itemRoles += 'tank';
    }

    if($scope.armor.role.healer) {
        if($scope.armor.itemRoles != '') {
            $scope.armor.itemRoles += ',healer';
        } else {
            $scope.armor.itemRoles += 'healer';
        }
    }

    if($scope.armor.role.dps) {
        if($scope.armor.itemRoles != '') {
            $scope.armor.itemRoles += ',dps';
        } else {
            $scope.armor.itemRoles += 'dps';
        }
    }

    console.log($scope.armor);

    $scope.armor.$update(id)
        .then(function(resp) {
            if(resp.success) {
                var message = resp.message;
                Flash.create('success', message, 'item-success');
                $scope.armors = armoringFactory.query();
            } else {
                var message = resp.message;
                Flash.create('success', message, 'item-success');
            }
        });
}

通过 PUT 方法发送的格式化数据(来自 console.log($scope.armor) ):

保存错误:

我还没有看到您采用的嵌套模式。这里有一些尝试(很难说是否真的如此,有很多事情要做):

var armoringSchema   = new Schema({
    itemType: String,
    itemClass: String,
    itemRoles: String,
    itemLevel: Number,
    itemName: String,
    itemRating: Number,
    itemStats: [{
      name: String,
      value: Number
    }]
});

我们还需要将一个对象传递给 $update 而不仅仅是一个数字。将 $scope.armor.$update(id) 更改为 $scope.armor.$update({id: id})