ЗНАЧИТЕЛЬНЫЙ стек новичка здесь. Наверное глупый вопрос задал.
В качестве упражнения я пытался реализовать прототип SPA, который показывает серию карточек задач на экране (вроде Trello).
На данный момент каждая карточка имеет 4 поля:
- _id: идентификатор объекта
- содержимое: строка
- рабочий процесс: строка
- состояние: строка
Я использую MongoDB для базы данных (ввел некоторые тестовые данные с помощью Robomongo), на моем компьютере установлен node.js, а также Express.js< /сильный>.
Мой файл server.js выглядит следующим образом:
var express = require('express'),
cards = require('./routes/cards');
var app = express();
app.configure(function() {
app.use(express.logger('dev'));
app.use(express.bodyParser());
});
app.get('/cards', cards.findAll);
app.get('/cards/:id', cards.findById);
app.post('/cards', cards.addCard);
app.put('/cards/:id', cards.updateCard);
app.listen(3000);
console.log('Listening on port 3000...');
Мои routes/cards.js на стороне сервера выглядят следующим образом:
var mongo = require('mongodb');
var Server = mongo.Server,
Db = mongo.Db,
BSON = mongo.BSONPure;
var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db('mindr', server);
db.open(function(err, db) {
if(!err) {
console.log("Connected to 'mindr' database");
db.collection('cards', {strict:true}, function(err, collection) {
if (err) {
console.log("The 'cards' collection doesn't exist.");
}
});
}
});
exports.findById = function(req, res) {
var id = req.params.id;
console.log('Retrieving card: ' + id);
db.collection('cards', function(err, collection) {
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
res.send(item);
});
});
};
exports.findAll = function(req, res) {
db.collection('cards', function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
};
exports.addCard = function(req, res) {
var newCard = req.body;
console.log('Adding card: ' + JSON.stringify(newCard));
db.collection('cards', function(err, collection) {
collection.insert(newCard, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
exports.updateCard = function(req, res) {
var id = req.params.id;
var card = req.body;
console.log('Updating card: ' + id);
console.log(JSON.stringify(card));
db.collection('cards', function(err, collection) {
collection.update({'_id':new BSON.ObjectID(id)}, card, {safe:true}, function(err, result) {
if (err) {
console.log('Error updating card: ' + err);
res.send({'error':'An error has occurred'});
} else {
console.log('' + result + ' document(s) updated');
res.send(card);
}
});
});
}
exports.deleteCard = function(req, res) {
var id = req.params.id;
console.log('Deleting card: ' + id);
db.collection('cards', function(err, collection) {
collection.remove({'_id':new BSON.ObjectID(id)}, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred - ' + err});
} else {
console.log('' + result + ' document(s) deleted');
res.send(req.body);
}
});
});
}
Когда я получаю карты из БД в своем контроллере AngularJS, все идет нормально. Все карты корректно отображаются на экране. Это код, который получает карты:
var mindrApp = angular.module('mindrApp', ['ngResource'])
mindrApp.controller('WorkflowController', function ($scope, $resource) {
var CardService = $resource("http://localhost:3000/cards/:cardId", {cardId:"@id"});
$scope.cards = CardService.query();
});
На каждой карточке есть несколько кнопок, которые можно использовать для изменения состояния карточки на следующее состояние, доступное в рабочем процессе (как определено доступными действиями текущего состояния).
При нажатии кнопки идентификатор карты и следующее состояние передаются функции в контроллере:
<div class="btn-group btn-group-xs">
<button type="button" class="btn btn-default"
ng-repeat="currentAction in currentState.actions | filter:{default:true}"
ng-click="processCard(currentCard._id, currentAction.next)">
{{currentAction.name}}
</button>
</div>
А это функция processCard в контроллере:
$scope.processCard = function(id, nextState) {
var currentCard = CardService.get({cardId: id}, function(){
currentCard.state = nextState;
currentCard.$save();
});
};
Происходит следующее: когда я нажимаю кнопку, вместо изменения состояния текущей карты создается новая карта с полем id типа String. Это вывод сервера:
Retrieving card: 52910f2a26f1db6a13915d9f
GET /cards/52910f2a26f1db6a13915d9f 200 1ms - 152b
Adding card: {"_id":"52910f2a26f1db6a13915d9f","content":"this is some content for this really cool card","workflow":"simple","state":"completed"}
Success: {"_id":"52910f2a26f1db6a13915d9f","content":"this is some content for this really cool card","workflow":"simple","state":"completed"}
POST /cards 200 1ms - 150b
Любая идея, почему это происходит? Почему он вызывает функцию addCard на сервере вместо вызова функции updateCard?