如何更新在ejs + mongoose中有多个值的表单?

用户在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> 

我真的需要循环每个领域? 如果我想更新具体的数据?

第一select:

根据你如何使用应用程序,你甚至可能不关心更新 – 你可以删除以前的教育,并保存新的教育。

第二个选项:

要正确地更新你真的需要一些你可以参考更新的ID,对吧?

你仍然需要使用你的for循环,你只需要插入id隐藏字段。

要做到这一点,你将需要传递一个对象,而不是一个唯一的string值。 我已经使我的对象数组看起来像这样:

 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] }); } 

还有一些注意事项:

  • 你必须检查每个教育logging的用户。 你不想让任何人混淆ID,毁掉别人的个人资料。
  • 您应该单独保存数组长度variables,在循环之外,因为它可能会导致非常大的数组上的性能问题,因为在每个循环迭代中parsing长度。

这是我会这样做的方式:

该模型:

 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将从input和值中读取数据ID,并将其放入一个教育对象数组中。 然后将对象添加string和string键“数据”。 这意味着你可以从req.body.data路线中的string并parsing它。

服务器端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]; } }; 

mongoose会自动给你的教育数组项目一个ID。 以上将使您能够添加,删除和更新页面上现有的教育项目。