如何更新在ejs + mongoose中有多个值的表单?
用户拥有猫鼬中的字段,如果用户决定更新,它将得到更新。如何更新在ejs + mongoose中有多个值的表单?
这里的用户模式
var User = Schema({
education: [{ type: String}],
});
所以基本上一个用户,他们可以更新或添加,例如用户可以添加额外的教育和使用形式的技能信息字段。
如何在ejs和路线中正确做到这一点?
我试图在route.js
router.post('/update-resume', function(req, res) {
User.findById(req.user._id, function(err, foundUser) {
// This part how do I update ?
if (req.body.education) foundUser.resume.education.push(req.body.education);
foundUser.save();
});
});
价值不断推进,我想,我知道这是很明显,我推数据到外地,但我怎么更新正常吗?
Form.ejs
<div class="form-group">
<label for="education">Education:</label>
<% for(var i = 0; i < user.resume.education.length; i++) { %>
<input type="text" class="form-control" name="education" id="education" value="<%= user.resume.education[i] %>">
<% } %>
</div>
这是真的,我需要为每个循环领域?如果我想更新具体数据?
第一种选择:
取决于你如何使用的应用程序,你可能甚至不关心更新 - 你可以只删除以前的教育和保存新的来代替。
第二个选项:
正确地更新你真的需要某种形式的,你可以参考更新时的ID的,对不对?
您仍然需要使用您的for
循环,您只需要插入id
隐藏字段。
为此,您需要传递一个对象而不是唯一的字符串值。我已经做了我的对象数组是这样的:
var education = [
{content:'Education 1',id:1},
{content:'Education 2',id:3},
{content:'Education 3',id:5},
{content:'Education 4',id:2},
];
然后,你可以做这样的事情:
<% for(var i = 0; i < education.length; i++) { %>
<input type="hidden" type="hidden" name="education_id" value="<%= education[i].id %>"/>
<input type="text" class="form-control" name="education" id="education" value="<%= education[i].content %>">
<% } %>
阵列总是会得到通过你它发送到服务器的方式。就我而言,我会得到这个(你可以看到,一切都在秩序,它应该是):
{education_id: [ '1', '3', '5', '2' ],
education: [ 'Education 1', 'Education 2', 'Education 3', 'Education 4' ] }
现在,让我们来看看POST后端,则需要配合一切回到一个对象(你并不真的需要,但你可以,也许应该理智的缘故):
var education_i;
var education_req = [];
for(education_i=0;education_i<req.body.education.length;education_i++) {
console.log(req.body.education[education_i]);
education_req.push({
content:req.body.education[education_i],
id:req.body.education_id[education_i]
});
}
一些更多的注意事项:
- 你必须检查每一个教育用户记录。你不想让任何人混淆ID并毁掉别人的个人资料。
- 您应该单独在循环外部保存数组长度变量,因为它可能会导致超大型数组上的性能问题,因为在每次循环迭代时会分析长度。
这是正路我会做到这一点:
型号:
var User = new Schema({
education: [{ content: String }]
});
的EJS/HTML:
<form id="education">
<% user.education.forEach(function(item) { %>
<input type="text" data-id="<%= item.id %>" value="<%= item.content %>" />
<% }); %>
<button type="submit">Save</button>
</form>
客户端的JavaScript(JQuery的):
$('#education').on('submit', function(e) {
e.preventDefault();
var data = [];
$(this)
.find('input')
.each(function() {
var $this = $(this);
// Collect the data with the id and value
data.push({
id: $this.data('id'),
value: $this.val()
});
});
$.ajax({
url: '/update-resume',
type: 'post',
data: { data: JSON.stringify(data) }
})
.done(function(data) {
if (data.success) {
// Lazy: refresh window
window.location.reload();
}
})
.fail(function() {
// Show an error or something fancy
});
});
上述JavaScript将从输入和值中读取数据ID并将其放入教育对象数组中。然后它会将对象添加和字符串串化为关键字'data'。这意味着你可以从req.body.data
的路线中拉出字符串并解析它。
服务器端JavaScript /的路线:
router.post('/update-resume', function(req, res, next) {
User.findById(req.user._id, function(err, user) {
var parsed = JSON.parse(req.body.data);
// update and remove
var results = user
.education
.filter(function(item) {
return parsed.some(function(input) {
return input.id === item.id;
});
})
.map(function(item) {
var related = getRelated(item.id, parsed);
return { content: related.value };
});
// Add new items
user.education = results
.concat(parsed.reduce(function(prev, curr) {
if (!getRelated(curr.id, results)) {
prev.push({ content: curr.value });
}
return prev;
}, []));
user.save(function(err) {
if (err) return next(err);
res.json({ success: true });
});
});
});
获得相关帮助:
var getRelated = function(id, arr) {
for (var i = 0; i < arr.length; i++) {
if (String(arr[i].id) === String(id)) return arr[i];
}
};
猫鼬会自动给你的教育数组项的ID。以上将允许您添加,删除和更新页面上的现有教育项目。
我试过了,特别是在JSON.parse中出现了很多错误 - >不断收到意外的令牌。你确定它是req.body.data?因为html是data-id。 –
杰克,我已经添加了客户端JavaScript的简要说明,以解释它做了什么。如果你在页面下方的页面上有它,它将完成所有艰苦的工作并对它创建的数组进行字符串化。应该没有解析错误,因为它只是一个字符串化的对象(由JSON完成,所以它应该是有效的)。你能粘贴错误吗? – Rick