在mongoose中保存多个动态添加的文件

时间:2017-10-07 08:39:42

标签: javascript node.js mongodb

我正在使用Ajax在表单中添加(和删除)多个字段,然后将它们提交给mongoose以保存它们。不幸的是,我只能检索并保存一个阵列,完全没有丢失的数据。

HTML:这是一个表单组可见的表单,其中我使用名称属性对数组进行了初始化,以及我用Ajax填充的表单组模板

<form id="productAdd" class="form-horizontal" method="post" enctype="multipart/form-data" action="?_csrf={{csrfToken}}">
  <section class="panel">
    <div class="panel-body">
      <div class="form-group" data-option-index="1">
        <label class="col-md-3 control-label" for="optionType">Type</label>
        <div class="col-md-1">
          <select class="form-control" name="options[0][optionType]">
            <option value="grams">Gr.</option>
          </select>
        </div>
        <label class="col-md-1 control-label" for="value">Value</label>
        <div class="col-md-1">
          <input type="text" class="form-control" name="options[0][optionValue]">
        </div>
        <label class="col-md-1 control-label" for="price">Price</label>
        <div class="col-md-1">
          <input type="text" class="form-control" name="options[0][optionPrice]">
        </div>
        <div class="col-md-1">
          <button type="button" class="btn btn-default addButton"><i class="fa fa-plus"></i></button>
        </div>
      </div>
      <div class="form-group hide" id="optionTemplate">
        <label class="col-md-3 control-label" for="optionType">Type</label>
        <div class="col-md-1">
          <select class="form-control" name="optionType">
            <option value="grams">Gr.</option>
          </select>
        </div>
        <label class="col-md-1 control-label" for="value">Value</label>
        <div class="col-md-1">
          <input type="text" class="form-control" name="optionValue">
        </div>
        <label class="col-md-1 control-label" for="price">Price</label>
        <div class="col-md-1">
          <input type="text" class="form-control" name="optionPrice">
        </div>
        <div class="col-md-1">
          <button type="button" class="btn btn-default removeButton"><i class="fa fa-minus"></i></button>
        </div>
      </div>
    </div>
    <footer class="panel-footer">
      <div class="row">
        <div class="col-sm-9 col-sm-offset-3">
          <input type="hidden" name="_csrf" value="{{csrfToken}}">
          <button class="btn btn-primary">Submit</button>
          <button type="reset" class="btn btn-default">Reset</button>
        </div>
      </div>
    </footer>
  </section>
</form>

AJAX:我使用它来添加行或删除行,每行包含3个输入。在提交表单之前,我使用.serialize()按名称获取数组

$(document).ready(function() {
  var optionIndex = $(".form-group[data-option-index]").length;
  $('#productAdd').submit(function(e) {  // add product submit function
    e.preventDefault();
    $(this).ajaxSubmit({
      contentType: 'application/json',
      data: $('form[name="productAdd"]').serialize(),
      error: function(xhr) {
        console.log('Error: ' + xhr.status + ' ---- ' + xhr.responseText);
      },
      success: function(response) {
        if (typeof response.redirect === 'string')
        window.location = response.redirect;
      }
    });
    return false;
  })

  // Add button click handler
  .on('click', '.addButton', function() {
    optionIndex++;
    var $template = $('#optionTemplate'),
      $clone = $template
        .clone()
        .removeClass('hide')
        .removeAttr('id')
        .attr('data-option-index', optionIndex)
        .insertBefore($template);
    // Update the name attributes
    $clone
      .find('[name="optionType"]').attr('name', 'options[' + optionIndex + '].optionType').end()
      .find('[name="optionValue"]').attr('name', 'options[' + optionIndex + '].optionValue').end()
      .find('[name="optionPrice"]').attr('name', 'options[' + optionIndex + '].optionPrice').end();
    })
  // Remove button click handler
  .on('click', '.removeButton', function() {
    var $row  = $(this).parents('.form-group'),
    index = $row.attr('data-option-index');
    // Remove fields
    $row.find('[name="options[' + index + '].title"]').remove();
    $row.find('[name="options[' + index + '].isbn"]').remove();
    $row.find('[name="options[' + index + '].price"]').remove();
    // Remove element containing the fields
    $row.remove();
  });
});

NODEJS:这是我的nodejs路由,我使用multer来管理文件上传。我有一个foreach应该管理表单中的输入,但它只是看到第一个元素。

router.post('/shop/products/add', [isLoggedIn, multer({dest: './public/images/products/'}).single('productPhoto')], function(req, res, next) {
  var newProduct = new Product();
  newProduct.imagePath = req.file.filename;
  newProduct.title = req.body.title;
  newProduct.description = req.body.description;
  newProduct.price = req.body.price;
  newProduct.save()
    .then(function (product) {
      console.log(req.body.options);
      req.body.options.forEach(function (option) {
        var newOption = new ProductOption();
        newOption.type = option.optionType;
        newOption.value = option.optionValue;
        newOption.price = option.optionPrice;
        newOption.product = product;
        newOption.save();
      });
    })
    .then(function (options) {
      req.flash('success', 'Product uploaded correctly.');
      res.send({redirect: '/user/shop/products/add'});
    })
    .catch(function (err) {
      console.log('Error ' + err.code + ': ', err.message);
      res.status(500).send('Failed to save the newAddress to DB: ' + err);
    });
});

1 个答案:

答案 0 :(得分:0)

这是一个简单的错误,我将这些字段命名为dinamically添加,与静态字段不同。

此代码

.find('[name="optionType"]').attr('name', 'options[' + optionIndex + '].optionType').end()

应该是这样的

.find('[name="optionType"]').attr('name', 'options[' + optionIndex + '][optionType]').end()