2015-11-04 15 views
4

用户拥有猫鼬中的字段,如果用户决定更新,它将得到更新。如何更新在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> 

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

回答

2

第一种选择:

取决于你如何使用的应用程序,你可能甚至不关心更新 - 你可以只删除以前的教育和保存新的来代替。

第二个选项:

正确地更新你真的需要某种形式的,你可以参考更新时的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并毁掉别人的个人资料。
  • 您应该单独在循环外部保存数组长度变量,因为它可能会导致超大型数组上的性能问题,因为在每次循环迭代时会分析长度。
2

这是正路我会做到这一点:

型号:

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。以上将允许您添加,删除和更新页面上的现有教育项目。

+0

我试过了,特别是在JSON.parse中出现了很多错误 - >不断收到意外的令牌。你确定它是req.body.data?因为html是data-id。 –

+0

杰克,我已经添加了客户端JavaScript的简要说明,以解释它做了什么。如果你在页面下方的页面上有它,它将完成所有艰苦的工作并对它创建的数组进行字符串化。应该没有解析错误,因为它只是一个字符串化的对象(由JSON完成,所以它应该是有效的)。你能粘贴错误吗? – Rick

相关问题