【问题标题】:Convert mutlidimensional inputs to JavaScript object将多维输入转换为 JavaScript 对象
【发布时间】:2017-03-31 22:17:45
【问题描述】:

我已经尝试解决这个问题好几天了,这让我发疯了。我有一些需要通过 Ajax 提交的数据。它是动态的,所以我不知道它有多少个字段。最重要的是,字段的名称是多维的,也是动态的。例如,一个可能有名称为 data[name]data[title] 的输入,而另一个较大的输入可能有 data[images][0][src]data[images][0][alt]data[images][0][description]data[images][1][src]data[images][1][alt]data[images][1][description],但数量未知数组中的元素。我的问题是我需要获取一个可以通过 Ajax 提交的对象,同时保持数据的结构。

我已经尝试对数据进行序列化,但只是得到了一串name = value。我也尝试过序列化数组,但这只是给了我一个[name, value] 的数组。我已经设法使用正则表达式手动生成对象以将其拆分,但我找不到将结果对象合并在一起的方法。我的代码的最新版本是:

$('.modal-content').find('input[name^="data"]').each(function () {
    var found = $(this).attr('name').match(re).reverse();
    var temp = $(this).val();
    $.each(found, function ()
    {
        str = this.substr(1, this.length - 2);
        var t = {};
        t[str] = temp;
        temp = t;
    });
    data = $.each({}, data, temp);
});

不幸的是,它没有合并它们,它用 temp 中的内容覆盖了 data 中的内容。如果 data 有 data.images[0].src = "mysrc" 而 temp 有 data.images[0].alt = "myalt" 那么我最终会得到 data.images[0].alt = "myalt" 并且 src 不再存在。

必须有一个简单的方法来做到这一点,在这一点上我什至会采取一种复杂的方式来做到这一点。有人可以帮我解决这个问题吗?

【问题讨论】:

  • HTML 本身是什么样的?它是动态的,但它是否完全遵循固定模式?
  • @RoryMcCrossan 唯一的共同因素是它们在一个带有 ID 的 div 中,并且它们都遵循name="data[x][y][z] 模式,其中 xyz 是动态的,并且存在未知数量的段。有些将是文本输入,其他单选按钮,一些选择和其他文本区域(我知道我只是在输入 atm,一旦为输入工作就会调整代码)
  • 实际的 HTML 很长,所以我在这里粘贴了迄今为止最复杂的版本 - pasted.co/0643034a
  • 您需要生成的 JSON 是什么样子的?
  • 你不能做一个数组,其中每个位置都有一个格式为{str: temp}的对象吗?

标签: javascript jquery multidimensional-array


【解决方案1】:

您可以使用each() 循环循环所有inputs,使用split()name 属性创建数组,然后使用reduce 添加到对象

var result = {}

$('input').each(function() {
  var name = $(this).attr('name');
  var val = $(this).val();

  var ar = name.split(/\[(.*?)\]/gi).filter(e => e != '');

  ar.reduce(function(a, b, i) {
    return (i != (ar.length - 1)) ? a[b] || (a[b] = {}) : a[b] = val;
  }, result)

})

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="gallery-images" class="ui-sortable">
  <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
    <div>
      <img src="http://localhost:8000/img/example.jpg">
      <input type="hidden" name="data[images][0][src]" value="img/example.jpg">
      <div class="form-group">
        <label for="title-0">Title:</label>
        <input type="text" name="data[images][0][title]" class="form-control" id="title-0" value="Default Example Image 1" placeholder="Title">
      </div>
      <div class="form-group">
        <label for="description-0">Description:</label>
        <input type="text" name="data[images][0][description]" class="form-control" id="description-0" value="A default example image." placeholder="Description">
      </div>
      <div class="form-group">
        <label for="alt-0">Alt tag (SEO):</label>
        <input type="text" name="data[images][0][alt]" class="form-control" id="alt-0" value="fluid gallery example image" placeholder="Alt tag">
      </div>
      <div class="form-group">
        <label for="order-0">Order:</label>
        <input type="number" name="data[images][0][order]" class="form-control image-order" id="order-0" value="0">
      </div>
      <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
    </div>
  </li>
  <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
    <div>
      <img src="http://localhost:8000/img/example.jpg">
      <input type="hidden" name="data[images][1][src]" value="img/example.jpg">
      <div class="form-group">
        <label for="title-1">Title:</label>
        <input type="text" name="data[images][1][title]" class="form-control" id="title-1" value="Default Example Image 2" placeholder="Title">
      </div>
      <div class="form-group">
        <label for="description-1">Description:</label>
        <input type="text" name="data[images][1][description]" class="form-control" id="description-1" value="A default example image." placeholder="Description">
      </div>
      <div class="form-group">
        <label for="alt-1">Alt tag (SEO):</label>
        <input type="text" name="data[images][1][alt]" class="form-control" id="alt-1" value="fluid gallery example image" placeholder="Alt tag">
      </div>
      <div class="form-group">
        <label for="order-1">Order:</label>
        <input type="number" name="data[images][1][order]" class="form-control image-order" id="order-1" value="1">
      </div>
      <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
    </div>
  </li>
  <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
    <div>
      <img src="http://localhost:8000/uploads/galleries\21\4-tux-30.jpg">
      <input type="hidden" name="data[images][2][src]" value="uploads/galleries\21\4-tux-30.jpg">
      <div class="form-group">
        <label for="title-2">Title:</label>
        <input type="text" name="data[images][2][title]" class="form-control" id="title-2" value="" placeholder="Title">
      </div>
      <div class="form-group">
        <label for="description-2">Description:</label>
        <input type="text" name="data[images][2][description]" class="form-control" id="description-2" value="" placeholder="Description">
      </div>
      <div class="form-group">
        <label for="alt-2">Alt tag (SEO):</label>
        <input type="text" name="data[images][2][alt]" class="form-control" id="alt-2" value="" placeholder="Alt tag">
      </div>
      <div class="form-group">
        <label for="order-2">Order:</label>
        <input type="number" name="data[images][2][order]" class="form-control image-order" id="order-2" value="2">
      </div>
      <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
    </div>
  </li>
  <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
    <div>
      <img src="http://localhost:8000/uploads/galleries\21\all-free-backgrounds-simple-style-darkblue-18.jpg">
      <input type="hidden" name="data[images][3][src]" value="uploads/galleries\21\all-free-backgrounds-simple-style-darkblue-18.jpg">
      <div class="form-group">
        <label for="title-3">Title:</label>
        <input type="text" name="data[images][3][title]" class="form-control" id="title-3" value="" placeholder="Title">
      </div>
      <div class="form-group">
        <label for="description-3">Description:</label>
        <input type="text" name="data[images][3][description]" class="form-control" id="description-3" value="" placeholder="Description">
      </div>
      <div class="form-group">
        <label for="alt-3">Alt tag (SEO):</label>
        <input type="text" name="data[images][3][alt]" class="form-control" id="alt-3" value="" placeholder="Alt tag">
      </div>
      <div class="form-group">
        <label for="order-3">Order:</label>
        <input type="number" name="data[images][3][order]" class="form-control image-order" id="order-3" value="3">
      </div>
      <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
    </div>
  </li>
</ul>

【讨论】:

【解决方案2】:

虽然已经有一个公认的答案。这是我的 5 美分:

恕我直言,应尽可能避免使用正则表达式。所以我的建议是稍微改变一下 HTML,向包含图像的 div 添加一些类并更改输入的 name 属性:

<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
        <div class="my-image">
            <img src="http://localhost:8000/img/example.jpg">
            <input type="hidden" name="src" value="img/example.jpg">
            <div class="form-group">
                <label for="title-0">Title:</label>
                <input type="text" name="title" class="form-control" id="title-0" value="Default Example Image 1" placeholder="Title">
            </div>
            <div class="form-group">
                <label for="description-0">Description:</label>
                <input type="text" name="description" class="form-control" id="description-0" value="A default example image." placeholder="Description">
            </div>
            <div class="form-group">
                <label for="alt-0">Alt tag (SEO):</label>
                <input type="text" name="alt" class="form-control" id="alt-0" value="fluid gallery example image" placeholder="Alt tag">
            </div>
            <div class="form-group">
                <label for="order-0">Order:</label>
                <input type="number" name="order" class="form-control image-order" id="order-0" value="0">
            </div>
            <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
        </div>
    </li>
    <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
        <div class="my-image">
            <img src="http://localhost:8000/img/example.jpg">
            <input type="hidden" name="src" value="img/example.jpg">
            <div class="form-group">
                <label for="title-1">Title:</label>
                <input type="text" name="title" class="form-control" id="title-1" value="Default Example Image 2" placeholder="Title">
            </div>
            <div class="form-group">
                <label for="description-1">Description:</label>
                <input type="text" name="description" class="form-control" id="description-1" value="A default example image." placeholder="Description">
            </div>
            <div class="form-group">
                <label for="alt-1">Alt tag (SEO):</label>
                <input type="text" name="alt" class="form-control" id="alt-1" value="fluid gallery example image" placeholder="Alt tag">
            </div>
            <div class="form-group">
                <label for="order-1">Order:</label>
                <input type="number" name="order" class="form-control image-order" id="order-1" value="1">
            </div>
            <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
        </div>
    </li>

然后构建匹配这个类的对象:

var obj = {
  data: {
    images: []
  }
}

var groups = $('.my-image');

groups.each(function(idx, el) {
  var child = {}
  $(el).find('input').each(function(jdx, info){
    var $info = $(info);
    child[$info.attr('name')] = $info.val();
  });

  obj.data.images.push(child);
});

我们会得到相同的结果,但它可能不太容易出错。这是plunker

【讨论】:

  • 感谢您的意见,但这正是我不想做的。因为输入是动态的,所以我必须为每种不同的类型多次编写代码。我不想写一个用于图像,一个用于视频,一个用于纯文本,一个用于横幅等。使用正则表达式,它适用于动态内容,无论我有什么输入字段,只要它们以 @ 开头987654324@ 它只是工作。
猜你喜欢
  • 2017-09-27
  • 2021-06-25
  • 1970-01-01
  • 2013-05-13
  • 2013-07-03
  • 2017-12-12
  • 2021-12-28
  • 2016-11-28
相关资源
最近更新 更多