我正在将Angular Fullstack用于Web应用程序。
我按$http.post()
对象发布数据:
{ title: "Some title", tags: ["tag1", "tag2", "tag3"] }
当我编辑对象并尝试执行$http.put()
以下操作时:
{ title: "Some title", tags: ["tag1"] }
在控制台中,我得到了,HTTP PUT 200
但是当我刷新页面时,我仍然使用所有3个标记来接收该对象。
这是我保存在MongoDB中的方式:
exports.update = function(req, res) {
if (req.body._id) {
delete req.body._id;
}
Question.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(responseWithResult(res))
.catch(handleError(res));
};
function saveUpdates(updates) {
return function(entity) {
var data = _.merge(entity.toJSON(), updates);
var updated = _.extend(entity, data);
return updated.saveAsync()
.spread(function(updated) {
return updated;
});
};
}
有人可以解释如何保存带有已删除项目的对象吗?
我做错了什么?
从数据库检索后,使用诸如_.merge
或_.extend
在客户端(意味着您的nodejs客户端到数据库而不是浏览器)代码中使用或之类的东西,这是非常糟糕的做法。同样值得注意的_.merge
是这里的问题,因为它不会“拿走”东西,而是“扩大”您提供的信息中已经存在的东西。这不是您想要的,但是还有更好的方法。
您应该只使用“原子运算符”$set
来代替:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": { "tags": req.body.tags } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
您实际上也应该以端点为目标,并且没有“通用”对象写操作。因此,对象只能专门针对相关“标签”的“ PUT”,而不会接触对象中的其他字段。
如果确实必须向其扔一个完整的对象并希望从所有内容中进行更新,请使用帮助程序来正确修复更新语句:
function dotNotate(obj,target,prefix) {
target = target || {},
prefix = prefix || "";
Object.keys(obj).forEach(function(key) {
if ( typeof(obj[key]) === "object" ) {
dotNotate(obj[key],target,prefix + key + ".");
} else {
return target[prefix + key] = obj[key];
}
});
return target;
}
var update = { "$set": dotNotate(req.body) };
Question.findByIdAndUpdateAsync(
req.params.id,
update,
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
无论您向其扔什么对象,哪种结构都将正确构造。
尽管在这种情况下,可能直接就足够了:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": req.body },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
原子运算符还有其他一些方法,您也可以将它们放入逻辑中进行处理。但最好考虑的是,您至少要对根文档属性以及像数组这样的东西分别作为子元素进行处理,才能对每个元素执行这些操作。
所有原子操作都与文档“在数据库中”和“修改时”交互。从数据库中提取数据,对其进行修改,然后再进行保存,这并不能保证数据尚未更改,而您可能会覆盖已经提交的其他更改。
我是真的,您的“浏览器客户端”应该已经意识到“标签”数组具有其他两个条目,然后您的“修改请求”应该只是$pull
要从数组中删除的条目,如下所示:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$pull": { "tags": { "$in": ["tag2", "tag3"] } } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
然后,无论“修改”服务器上文档的当前状态如何,这些更改都是唯一的更改。因此,如果在添加的“ tag4”处进行了其他修改,并且客户端在发送修改之前尚未获得此类更改的通知,则返回响应也将包括该更改,并且所有内容将保持同步。
了解MongoDB的更新修饰符,因为它们会很好地为您服务。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句