Метод обновления Angular Resource с массивом в качестве параметра

Я искал это в течение нескольких недель без реального разрешения.

Я уверен, что кто-то отметит это как дубликат, но я не уверен, что это действительно так, может быть, я просто слишком конкретен, так или иначе.

Я использую angular в приложении node-webkit, которое я создаю. У меня есть API, встроенный в Express, и я использую MongoDB (@mongolab) с Mongoose для БД.

У меня это работало нормально, пока все типы данных были простыми строками и числами. но мне пришлось реструктурировать данные, чтобы использовать массивы и сложные объекты. После реструктуризации данных я смог заставить почтовые вызовы 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)):

введите здесь описание изображения

Ошибка при сохранении:

введите здесь описание изображения


person AverageJoe    schedule 11.07.2015    source источник


Ответы (1)


Я не видел схем вложения так, как вы это делаете. Вот кое-что, что можно попробовать (трудно сказать, точно ли это, много всего происходит):

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}).

person Andy Gaskell    schedule 11.07.2015
comment
Энди, спасибо за совет. Это работает так же для добавления новых доспехов, как и то, что я делаю, я полагаю, что это более читабельно и проще для понимания, поэтому я буду использовать его в будущем (хотя забавно, клянусь, я пробовал это в прошлом, и это не сработало ). Однако это не решает мою проблему редактирования, так как я все равно получаю тот же результат. - person AverageJoe; 11.07.2015
comment
Спасибо, Энди, это сработало как шарм. Я должен тебе пиво :D - person AverageJoe; 11.07.2015