我对猫鼬/快递很陌生。我正在努力从html表单中更新新数据,并将其保存到具有引用的数据库中。我有一个商业模式,位置参考位置模型。这是密码。
edit.ejs
<div class="container">
<div class="form-container">
<form action="/<%= bus._id %>?_method=PUT" method="POST">
<!-- business info -->
<h3>Business Information</h3>
<input class="form-input" type="input" name="bus[logo]" value="<%= bus.logo %>">
<input class="form-input" type="input" name="bus[name]" value="<%= bus.name %>">
<% bus.location.forEach(function(location) { %>
<input class="form-input" type="input" name="bus.location[street]" value="<%= location.street %>">
<input class="form-input" type="input" name="bus.location[city]" value="<%= location.city %>">
<div class="state-input">
<select class="form-inline" name="bus.location[state]">
<option value="" disabled selected><%= location.state %></option>
<option value="AL">Alabama</option>
...
<option value="WY">Wyoming</option>
</select>
</div><!--State-input -->
<input class="form-inline" type="input" name="bus.location[zipcode]" value="<%= location.zipcode %>">
<% }) %>
<!--Contact info-->
<h4>Contact Information</h4>
<% bus.contact.forEach(function(contact) { %>
<input class="form-input" type="url" name="bus[url]" value="<%= bus.url %>">
<input class="form-input" type="email" name="bus.contact[email]" value="<%= contact.email %>">
<input class="form-input" type="tel" name="bus.contact[phone]" value="<%= contact.phone %>">
<input class="form-input" type="input" name="bus.contact[twitter]" value= "<%= contact.twitter %>">
<input class="form-input" type="input" name="bus.contact[facebook]" value="<%= contact.facebook %>">
<input class="form-input" type="input" name="bus.contact[instagram]" value="<%= contact.instagram %>">
<% }) %>index.js -编辑路由
//(edit.ejs) Edit Route
app.get('/:id/edit', function(req, res) {
Business.findById(req.params.id)
.populate('location')
.populate('contact')
.populate('images')
.exec(function(err, bus) {
if(err) {
console.log(err);
} else {
res.render('edit', {bus:bus});
}
});
});
app.put('/:id', function(req, res) {
Business.findByIdAndUpdate(req.params.id, req.body.bus, function(err, bus) {
if(err) {
console.log(err);
res.redirect('/' + req.params.id + '/edit');
} else {
res.redirect('/' + req.params.id);
}
});
});业务(总线)更新得很好,但是bus.location没有更新。商业模式
//----------------------------------------------------------------------------\\
var mongoose = require('mongoose');
//----------------------------------------------------------------------------\\
var busSchema = new mongoose.Schema({
name: String,
type: String,
logo: String,
desc: String,
subs: Number,
video: String,
url: String,
firstRun: Boolean,
location:[
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Location'
}
],
contact:[
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Contact'
}
],
images:[
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Image'
}
],
comments:[
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
],
created: {
type: Date, default: Date.now
}
});
//----------------------------------------------------------------------------\\
module.exports = mongoose.model('Business', busSchema);区位模型
//----------------------------------------------------------------------------\\
var mongoose = require('mongoose');
//----------------------------------------------------------------------------\\
var locSchema = new mongoose.Schema(
{
street: String,
city: String,
state: String,
zipcode: Number
}
);
//----------------------------------------------------------------------------\\
module.exports = mongoose.model('Location', locSchema);发布于 2017-05-04 01:42:50
Business、Location和Contact是不同的集合。
findByIdAndUpdate只更新一个集合,特别是Business。为了更新其他集合,需要对这些集合执行操作。
如果您试图更新“现有”位置和联系人,则还需要提供它们的ID。而且,您有一个位置和联系人的“数组”,因此您需要在名称中添加额外的[]。
<% bus.location.forEach(function(location, i) { %>
<input type="hidden" name="location[<?= i ?>][id]" value="<%= location.id %>">
<input class="form-input" type="input" name="location[<?= i ?>][street]" value="<%= location.street %>">
<!-- etc -->
<% }) %>
<% bus.contact.forEach(function(contact, i) { %>
<input type="hidden" name="contact[<?= i ?>][id]" value="<%= contact.id %>">
<input class="form-input" type="email" name="contact[<?= i ?>][email]" value="<%= contact.email %>">
<!-- etc -->
<% }) %>根据我(和其他)的经验,我认为不可能一次更新多个文档。这意味着,在路由处理程序中,需要迭代给定数组中的每个项并逐个更新它们。不过,另一篇文章中的答案并不完全正确,海事组织,因为您不应该使用同步forEach来执行异步猫鼬操作,因为它会导致意外的行为。
您有三项主要任务要做:更新业务、更新现有位置和更新现有联系人。
我喜欢使用async.js执行多个异步操作。在您的特殊情况下,我将使用async.series来执行每个任务,使用async.eachSeries对数组的每个元素执行操作。
警告这是未经测试的,但它看起来如下所示:
app.put('/:id', function(req, res) {
console.log(req.body.bus);
console.log(req.body.location); // should be an array of objects
console.log(req.body.contact); // should be an array of objects
// perform each task one by one
async.series([
function updateBusiness (done) {
// you need to always call the callback i.e. done to indicate the task is "done"
// - if you pass an error as an argument, it means the task failed and stop everything
// - otherwise, move onto the next task
/*Business.findByIdAndUpdate(req.params.id, req.body.bus, function (err) {
if (err) {
return done(err); // task failed and stop everything
}
done(); // task went well and proceed to the next task
});*/
// simplified
Business.findByIdAndUpdate(req.params.id, req.body.bus, done);
},
function updateLocations (done) {
// find and update each location
async.eachSeries(req.body.location || [], function (location, done2) {
Location.findByIdAndUpdate(location.id, location, done2);
}, done);
},
function updateContacts (done) {
// find and update each contact
async.eachSeries(req.body.contact || [], function (contact, done2) {
Contact.findByIdAndUpdate(contact.id, contact, done2);
}, done);
}
], function allDone (err) {
// a task failed somewhere
if (err) {
console.log(err);
res.redirect('/' + req.params.id + '/edit');
// all tasks were completed
} else {
res.redirect('/' + req.params.id);
}
});
});如果出现错误,请查看控制台日志。
https://stackoverflow.com/questions/43771903
复制相似问题