将嵌套列表写为结构化JSON

时间:2017-06-29 21:57:12

标签: javascript jquery json

我使用jQuery将嵌套列表写为JSON。

我遇到围绕嵌套元素的问题。我创建了一个Plunk,只需单击一下按钮即可用于重新创建问题。

插入https://plnkr.co/edit/jLi9epblNAtMbzezcRSY?p=preview

HTML:

<h1>Hello Plunker!</h1>
<div class="dd" name="agenda-nestable" id="nestable">
    <ol id="agenda-root" class="dd-list">
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Pledge of Allegiance</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Roll Call</div>
                    <ol class="dd-list">
                            <li class="dd-item" data-id="0">
                            <div class="dd-handle">Establish a Quorum</div></li>
                    </ol>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Public Comment</div>
                    <ol class="dd-list">
                            <li class="dd-item" data-id="0">
                            <div class="dd-handle">Address</div></li>
                            <li class="dd-item" data-id="0">
                            <div class="dd-handle">Open Floor</div></li>
                    </ol>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Action to set agenda and to approve consent agenda items</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Presentations and awards</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Matters set for a specific time</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Regular Agenda</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Governing Board</div>
            </li>
            <li class="dd-item" data-id="0" id="0">
                <div class="dd-handle">Closed Session</div>
            </li>
    </ol>
</div>
<pre id="jsonOutput"></pre>
<button value onclick='convertToJson()'>Convert nodes to JSON</button>

代码:

function convertToJson() {
  var sectionOrder = "";
  var itemOrder = "";
  var sectionDelimiter = "";
  var itemDelimiter = "";

  var agendaDiv = $("[name='agenda-nestable']");
  var agendaSections = $(agendaDiv).find("ol#agenda-root>li");
  var sections = [];

  for (var i = 0; i < agendaSections.length; i++) {
      var agendaSection = agendaSections[i];
      var section = {};
      section.Id = $(agendaSection).attr('data-id');
      section.SectionText = $(agendaSection).find("div:first-child").text(); // Something wrong here
      section.Items = [];

      var sectionItems = $(section).find("ol>li");
      for (var j = 0; j < sectionItems.length; j++) {
          var sectionItem = sectionItems[j];
          var item = {};
          item.Id = $(sectionItem).attr('data-id');
          item.ItemText = $(sectionItem).find("div:first-child").text(); // Something wrong here
          section.Items.push(item);
      }
      sections.push(section);
  }
  var json = JSON.stringify(sections, null, 2);;
  $('#jsonOutput').text(json);
  console.log(json);
  return json;
}

输出:

  {
    "Id": "0",
    "SectionText": "Pledge of Allegiance",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Roll CallEstablish a Quorum", // THIS IS WRONG, should be in Items Array, not munged together
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Public CommentAddressOpen Floor", // THIS IS WRONG, should be in Items Array, not munged together
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Action to set agenda and to approve consent agenda items",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Presentations and awards",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Matters set for a specific time",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Regular Agenda",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Governing Board",
    "Items": []
  },
  {
    "Id": "0",
    "SectionText": "Closed Session",
    "Items": []
  }
]

非常感谢您看一看,我真的很感激!!!

菲利普

3 个答案:

答案 0 :(得分:1)

var section = {};

var sectionItems = $(section) .find(“ol&gt; li”);

这是你的问题。您尝试将object用作jquery元素。

改为使用 $(agendaSection)

此外,您的li元素具有相同的 id ,这是不允许的。

$(document).ready(function () {

  function convertToJson() {

    var nestable = $("#nestable"),
      root = $('#agenda-root'),
      agendaSections = $("#agenda-root>li"),
      sections = [];
    
    agendaSections.each(function() {
      var section = {};
      section.Id = $(this).attr('data-id');
      section.SectionText = $(this).find(".dd-handle").first().text(); // Something wrong here
      section.Items = [];
      
      $(this).find('.dd-list').find('.dd-item').each(function() {
        var item = {};
        item.Id = $(this).attr('data-id');
        item.ItemText = $(this).find(".dd-handle").first().text(); // Something wrong here
        section.Items.push(item);
      })
      sections.push(section);
    });
    
    var json = JSON.stringify(sections, null, 2);
    $('#jsonOutput').text(json);
    console.log(json);
    return json;
  }

  $('#toJson').click(convertToJson);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dd" name="agenda-nestable" id="nestable">
    <ol id="agenda-root" class="dd-list">
      <li class="dd-item" data-id="1" id="1">
        <div class="dd-handle">Pledge of Allegiance</div>
      </li>
      <li class="dd-item" data-id="2" id="2">
        <div class="dd-handle">Roll Call</div>
        <ol class="dd-list">
          <li class="dd-item" data-id="1">
            <div class="dd-handle">Establish a Quorum</div>
          </li>
        </ol>
      </li>
      <li class="dd-item" data-id="3" id="3">
        <div class="dd-handle">Public Comment</div>
        <ol class="dd-list">
          <li class="dd-item" data-id="1">
            <div class="dd-handle">Address</div>
          </li>
          <li class="dd-item" data-id="2">
            <div class="dd-handle">Open Floor</div>
          </li>
        </ol>
      </li>
      <li class="dd-item" data-id="4" id="4">
        <div class="dd-handle">Action to set agenda and to approve consent agenda items</div>
      </li>
      <li class="dd-item" data-id="5" id="5">
        <div class="dd-handle">Presentations and awards</div>
      </li>
      <li class="dd-item" data-id="6" id="6">
        <div class="dd-handle">Matters set for a specific time</div>
      </li>
      <li class="dd-item" data-id="7" id="7">
        <div class="dd-handle">Regular Agenda</div>
      </li>
      <li class="dd-item" data-id="8" id="8">
        <div class="dd-handle">Governing Board</div>
      </li>
      <li class="dd-item" data-id="9" id="9">
        <div class="dd-handle">Closed Session</div>
      </li>
    </ol>
  </div>

  <pre id="jsonOutput"></pre>
  <button type="button" id="toJson">Convert nodes to JSON</button>

这是它的工作原理。

答案 1 :(得分:1)

您的JS中存在两个问题。

问题:1

find(&#34; div:first-child&#34;)将匹配所有div:first-child,这就是为什么div下的文本&gt;李也被抓获了。所以改变行

 $(agendaSection).find("div:first-child").text();

$(agendaSection).find("> div:first-child").text();

问题:2

你需要在找到ol时传递agendaSection,而不是section,它是一个包含对象的变量。

var sectionItems = $(agendaSection).find("ol>li");

答案 2 :(得分:1)

问题1:文本汇集在一起​​:

JQuery .text()返回源节点下所有子节点的文本内容。这就是为什么你得到&#34; Public CommentAddressOpen Floor&#34;。 http://api.jquery.com/text/

有关避免此问题的一些方法,请参阅此答案:jQuery: exclude children from .text()。这里详细说明了避免此问题的明确方法:http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/

问题2:为什么没有项目?

一旦修复,你仍然没有子项目。这是一个很好的提示:如果您的输出不是您所期望的,请检查您的输入。在这种情况下,您的选择器是错误的。您是从输出数组中选择的,而不是您的jQuery部分列表。换句话说,这个:

$(section).find("ol>li");

应该是这样的:

agendaSection.find("ol>li");

这是一支有效的笔:

https://codepen.io/anon/pen/awqwEV

在笔中,我还冒昧地使用$为jQuery变量添加前缀,并在变量赋值下执行jQuery赋值。所以,agendaSection现在是$ agendaSection,而jQuery只做了一次包装该元素的工作。从长远来看,这些都是很好的做法。