Javascript 为什么全堆栈角度生成器使用Lo Dash';是否合并而不是document.set?
这是用于更新的默认代码:Javascript 为什么全堆栈角度生成器使用Lo Dash';是否合并而不是document.set?,javascript,angularjs,mongoose,yeoman,lodash,Javascript,Angularjs,Mongoose,Yeoman,Lodash,这是用于更新的默认代码: exports.update = function(req, res) { if(req.body._id) { delete req.body._id; } Thing.findById(req.params.id, function (err, thing) { if (err) { return handleError(res, err); } if(!thing) { return res.send(404); } var upd
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Thing.findById(req.params.id, function (err, thing) {
if (err) { return handleError(res, err); }
if(!thing) { return res.send(404); }
var updated = _.merge(thing, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, thing);
});
});
};
注意下面这行代码:var updated=u.merge(thing,req.body)代码>。这仅适用于作为基本体的架构属性。它不适用于作为数组的模式属性
问题是thing
是一个mongoose文档,req.body
是一个javascript对象
我对真正的问题有两个假设:
要求第一个参数是对象,但它是
接收文件李>
_.merge()仅当两个对象具有相同的键和类型时才会合并。因为一个是文档,另一个是对象,所以它们是
不一样
考虑这个例子<代码>名称
已正确更新,但arr
未正确更新。但是,当我使用thing.set(req.body)
而不是var updated=.\uu.merge(thing,req.body)
时,这两个属性都得到了正确的更新
thing.html
<div class="container">
<form ng-submit="update()">
<div class="form-group">
<label>Name</label>
<input class="form-control" ng-model="thing.name">
</div>
<div class="form-group">
<label>Arr</label>
<input
type="text"
class="form-control"
ng-repeat="el in thing.arr"
ng-model="thing.arr[$index]">
</div>
<button
class="btn btn-default"
type="submit">
Update
</button>
</form>
{{thing | json}}
</div>
thing.model.js
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ThingSchema = new Schema({
name: String,
arr: []
});
module.exports = mongoose.model('Thing', ThingSchema);
thing.controller.js(后端)
两个问题:
对u.merge返回值调用“markModified”(正如前面的答案所建议的那样)并没有解决我的这个问题。Adam Zerner报告的问题是_merge导致“updated”对象包含数组属性的无效数据。我在使用angular fullstack generator时也遇到了这个问题,例如,如果我从数组中删除元素,则此更改不会存储在Mongoose/mongo中。调用mongoose文档上的set函数(例如,Zerner建议的thing.set(…)为我解决了这个问题。我还阅读了这个讨论线程:;它建议将_merge替换为_extend(另请参见),这也适用于我。我从Lodash 3.10.1升级到了4.6.1(最新版本)和u.merge现在可以按您的需要工作。我已经有一段时间遇到了这个问题,使用最新版本的generator angular fullstack(3.3.0)将u.merge更改为u.assign在以前的版本中,它对我不起作用。Lodash的v4.6.1版本似乎可以实现这一点,尽管我看到许多npm模块将Lodash的v3.10.1版本列为依赖项,但我还没有遇到任何问题。是-。我删除了它,因为我使用的是
set()
,但我只是将其取消删除以供您参考。@JohnnyHK绝对正确!您是对的,我应该在一开始就这样做。我用新的示例编辑了这个问题。在这种情况下,您需要手动将arr
字段标记为已修改,因为您尚未定义其元素包含的内容,所以Mongoose无法判断它何时被修改。updated.markModified('arr');
@johnyhk好的,谢谢。你认为这比使用set
有优势吗?也许它更快,因为它只是合并更新的内容,而不是所有内容?请参阅user3608315的答案
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ThingSchema = new Schema({
name: String,
arr: []
});
module.exports = mongoose.model('Thing', ThingSchema);
'use strict';
var _ = require('lodash');
var Thing = require('./thing.model');
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Thing.findById(req.params.id, function (err, thing) {
if (err) { return handleError(res, err); }
if(!thing) { return res.send(404); }
var updated = _.merge(thing, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, thing);
});
});
};
function handleError(res, err) {
return res.send(500, err);
}
var updated = _.merge(store, req.body);
updated.markModified('foo_name');
updated.save(function (err) {
if (err) {
return handleError(res, err);
}
return res.json(200, store);
});