Node.js Mongoose-使用嵌入文档保存模型的表单

Node.js Mongoose-使用嵌入文档保存模型的表单,node.js,express,mongoose,Node.js,Express,Mongoose,无法将嵌入式阵列保存到Mongoose模型 请参见底部的编辑。 我有一个在Express中使用Mongoose在mongo中存储数据的表单来创建BlogPost。我可以创建和查看新的BlogPost,但我只是在BlogPost模型中添加了一个嵌入式文档模式提要,无法将提要数组从表单保存到模型中 代码: BlogPosts.js var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/my_database

无法将嵌入式阵列保存到Mongoose模型

请参见底部的编辑。

我有一个在Express中使用Mongoose在mongo中存储数据的表单来创建BlogPost。我可以创建和查看新的BlogPost,但我只是在BlogPost模型中添加了一个嵌入式文档模式提要,无法将提要数组从表单保存到模型中

代码:

BlogPosts.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');

var Schema = mongoose.Schema
  , ObjectId = Schema.ObjectId;

var Feeds = new Schema({
    name      : { type: String }
  , key       : { type: String }
});

var BlogPost = new Schema({
    author    : ObjectId
  , title     : { type: String, required: true, index: { unique: true } }
  , date      : { type: Date, required: true, default: Date.now }
  , feeds     : [Feeds]
});

mongoose.model('BlogPost', BlogPost);
web.js

...
app.get('/blogpost/new', function(req, res) {
    res.render('blogposts/blogpost_new.jade', { locals: {
        title: 'New BlogPost'
    }
    });
});

app.post('/blogpost/new', function(req, res){
    var b = new BlogPost(req.body.b)
    b.save(function() {
      b.feeds.push();
      res.redirect('/blogposts');
    });
});
...
var BlogPost = mongoose.model('BlogPost', BlogPost);
玉形

form( method="post")
  div
    div
      span Title :
      input(type="text", name="b[title]", id="editBlogPostTitle")
    div 
      span Feeds :
      ul 
        li 
          span name
          textarea( name="f[name]", rows=20, id="editBlogPostBodyName")
        li
          span key
          textarea( name="f[key]", rows=20, id="editBlogPostBodyKey")
    div#editBlogPostSubmit
      input(type="submit", value="Send")
如果我填写此表单,模型将发布和保存,但提要数据不在那里(
“提要”:[]

如何正确提交提要数据以保存到阵列

编辑

因此,我成功地设置了一个表单,在BlogPost中使用
name
key
保存提要对象,并执行以下操作。然而,这仍然需要改进,以允许在创建单个BlogPost时保存多个提要。使用我当前的解决方案,我只能正确保存一个提要。想法

blogposts.js(只需将Feed更改为Feed

var Feed = new Schema({
...
web.js(刚刚移动推送)

}))

表单(只需更改提要名称)

这样可以正确地保存,在保存时我不能在一篇博客文章中创建多个提要。非常感谢您的帮助。谢谢。

路线:

您不需要执行
b.feeds.push()在立柱侧。在创建新对象时,我在get端有一个按钮,但这只是因为我希望至少有一个嵌套模型。然后再次说明,如果您有一个列表,您可能需要添加
b.feeds.push()也在get端

对于视图,需要保持模型完整

假设b是blogpost,并且是f列表的父级,那么您需要:

span Feeds :
  - var i = 0;
  ul
  - each feed in blogPost.feeds
    li 
      span name
      textarea( name="blogPost[feeds][i][name]", rows=20, id="editBlogPostBodyName")=feed.name
    li
      span key
      textarea( name="blogPost[feeds][i][key]", rows=20, id="editBlogPostBodyKey")=feed.key
    - i++
routes.js(或routes/blogPosts.js):

编辑我将b改为blogPost,f改为在视图中提要。在路由定义中还添加了“新”逻辑

另一方面,请记住,在这种情况下,任何管线都是不可编辑的。理论上,它应该在编辑它们的时候删除并保存任何新的提要(如果你有一个更新操作)。如果您希望它们是可以编辑的独立实体,那么您需要为它们提供id,并添加一种通过id获取它们的方法。我相信mongoosejs.com上概述了这种方法。

对于路由:

您不需要执行
b.feeds.push()在立柱侧。在创建新对象时,我在get端有一个按钮,但这只是因为我希望至少有一个嵌套模型。然后再次说明,如果您有一个列表,您可能需要添加
b.feeds.push()也在get端

对于视图,需要保持模型完整

假设b是blogpost,并且是f列表的父级,那么您需要:

span Feeds :
  - var i = 0;
  ul
  - each feed in blogPost.feeds
    li 
      span name
      textarea( name="blogPost[feeds][i][name]", rows=20, id="editBlogPostBodyName")=feed.name
    li
      span key
      textarea( name="blogPost[feeds][i][key]", rows=20, id="editBlogPostBodyKey")=feed.key
    - i++
routes.js(或routes/blogPosts.js):

编辑我将b改为blogPost,f改为在视图中提要。在路由定义中还添加了“新”逻辑


另一方面,请记住,在这种情况下,任何管线都是不可编辑的。理论上,它应该在编辑它们的时候删除并保存任何新的提要(如果你有一个更新操作)。如果你想让它们成为可以编辑的独立实体,那么你需要为它们提供id,并添加一种通过id获取它们的方法。我相信mongoosejs.com上概述了这种方法。

我确实做到了这一点。请参阅上面我的编辑,在我向提要名称添加[]后,该编辑生效:
“提要[0][name]”和“提要[0][key]”
,然后是
“提要[1][name]”和“提要[1][key]”
。谢谢你给我一些好主意。对我来说,把这种逻辑放在“获取”路线上是行不通的,它需要放在“发布”路线上。非常感谢。

不管它值多少钱,我确实让它发挥了作用。请参阅上面我的编辑,在我向提要名称添加[]后,该编辑生效:
“提要[0][name]”和“提要[0][key]”
,然后是
“提要[1][name]”和“提要[1][key]”
。谢谢你给我一些好主意。对我来说,把这种逻辑放在“获取”路线上是行不通的,它需要放在“发布”路线上。非常感谢。

我不是100%支持=f.name/=f.key,因为我刚从haml转到jade,但我想这是对的,我喜欢这是怎么回事。我现在得到:在
-I++
行上有一个引用错误,它说
b没有定义
我想我需要在app.get new中以一种可用的方式定义b。是的,尽管我建议使用更有意义的名称。比如博客。我将编辑我的答案,包括我将使用的get。我想这个问题太大,太模糊了。。。这是我的错。我不是100%的使用=f.name/=f.key,因为我刚从haml切换到jade,但我认为这是对的,我喜欢这一切。我现在得到:在
-I++
行上有一个引用错误,它说
b没有定义
我想我需要在app.get new中以一种可用的方式定义b。是的,尽管我建议使用更有意义的名称。比如博客。我将编辑我的答案,包括我将使用的get。我想这个问题太大,太模糊了。。。那是我的错。
span Feeds :
  - var i = 0;
  ul
  - each feed in blogPost.feeds
    li 
      span name
      textarea( name="blogPost[feeds][i][name]", rows=20, id="editBlogPostBodyName")=feed.name
    li
      span key
      textarea( name="blogPost[feeds][i][key]", rows=20, id="editBlogPostBodyKey")=feed.key
    - i++
app.get('/blogpost/new', function(req, res) {
    post = new BlogPost();
    post.feeds.push(new Feed());
    res.render('blogposts/blogpost_new.jade', { locals: {
        title: 'New BlogPost',
        blogPost: post
    }
    });
});