【问题标题】:React treeview from JSON array从 JSON 数组反应树视图
【发布时间】:2018-04-21 11:19:51
【问题描述】:

我正在使用 React 从 JSON 制作树视图。到目前为止,我已经使用这个示例数据制作了一个可折叠的树:

var data = {
      title: "Node 1",
      childNodes: [
        {title: "Childnode 1.1"},
        {title: "Childnode 1.2",
          childNodes: [
            {title: "Childnode 1.2.1",
              childNodes: [
                {title: "Childnode 1.2.1.1"}
              ]}, {title: "Childnode 1.2.2"}
          ]}
      ]
    };

但这是一个对象。我想获取 JSON 对象数组作为输入并从中生成树视图,但我无法理解在哪里更改代码。

这是我的渲染函数:

render() {
    var childNodes;

    if (this.props.node.childNodes != null) {
      childNodes = this.props.node.childNodes.map(function (node, index) {
        return <li key={index}><Treeview node={node}/></li>
      });
    }

    return (
      <form>
        <div>
          <input type="checkbox"/>
          <label for>{this.props.node.title}</label>
        </div>
        <ul>
          {childNodes}
        </ul>
      </form>

    );
  }

如何更改代码以使用整个数组而不仅仅是一个对象?

【问题讨论】:

  • 所以你想让 Treeview 组件接受一个对象数组?或者您想将数组转换为 Treeview 的对象?
  • 我想让Treeview组件接受一个对象数组,例如:[{"id":28,"Title":"Sweden"}, {"id":56,"Title" :"USA"}, {"id":89,"Title":"England"}]
  • 好的,让我看看 Treeview 组件的代码
  • 我发布的代码是 Treeview 组件。我在 Treeview 中渲染这个代码块,即递归

标签: javascript json reactjs recursion treeview


【解决方案1】:

递归很有趣!

const data = [{
  title: "Node 1",
  childNodes: [
    { title: "Childnode 1.1" },
    {
      title: "Childnode 1.2",
      childNodes: [
        {
          title: "Childnode 1.2.1",
          childNodes: [
            { title: "Childnode 1.2.1.1" }
          ]
        }, { title: "Childnode 1.2.2" }
      ]
    }
  ]
}];

const App = () => (
  <form>
    <Tree data={data} />
  </form>
);

const Tree = ({data}) => ( 
  <ul>
    {data && data.map(item => (
      <li>
        {item.title}
        {item.childNodes && <Tree data={item.childNodes} />}
      </li>
    ))}
  </ul>
);

演示:https://codesandbox.io/s/01kl2xmo40

【讨论】:

  • 非常感谢。有效。是否有任何方法可以将父节点和子节点的“div”分开,以便在切换复选框时树可以折叠?
  • 抱歉,我更新为使用列表项而不是 div。只需在 ul 上放置一个 onClick 处理程序并切换树组件的“可见性”状态,然后根据它有条件地渲染。您必须使其成为有状态的类组件(而不是当前的无状态功能组件)。
  • 可以分享一下toggle相关的代码吗?
  • codesandbox.io/s/unruffled-babbage-9knrz。这里如何修复切换选项
【解决方案2】:

下面的这个例子可以在我测试过的所有 json 对象上工作 查看我的 github 仓库:https://github.com/nickjohngray/blockout/blob/master/src/Tree/Tree.tsx 生成的html同https://www.w3schools.com/howto/howto_js_treeview.asp

class Tree extends React.Component {

   

    processObject = (object) =>
        Object.keys(object).map((key, reactKey) => {
            return (
                <li key={reactKey + key}>
                    {this.buildNode(key)}
                    <ul className="nested">
                        {this.isPrimative(object[key]) ? this.buildLeaf(object[key]) :
                            this.isArray(object[key]) ? this.loopArray(object[key]) : this.processObject(object[key])}
                    </ul>
                </li>
            )
        })

    loopArray = (array) =>
        array.map((value, key) =>
            <div key={key + value}>
                {this.isPrimative(value) ? this.buildLeaf(value) :
                    this.isArray(value) ? this.loopArray(value) : this.processObject(value)}
            </div>
        )

    isArray = (value) =>
        Array.isArray(value)

    isPrimative = (value) => {
        return typeof (value) === 'string'
            || typeof (value) === 'number'
            || typeof (value) === 'boolean'
    }

    buildNode = (key: string) =>
        <span className="node"
              onClick={
                  (e) => {
                      this.toggle(e)
                  }}>
             {key}
            </span>

    buildLeaf = (value: string) =>
        <li className="leaf"
            onClick={
                (e) => {

                }}>
            {value}
        </li>

    toggle = (event) => {
        event.target.parentElement.querySelector(".nested").classList.toggle("active");
        event.target.classList.toggle("node-down");
    }

    render = () => <>
        <ul id="myUL">
            {this.processObject(json)}
        </ul>
    </>
}

export default Tree;

这是它的css,抄自wc3学校

/* Remove default bullets */
ul, #myUL {
    list-style-type: none;
}

body {
    background: red;
}


/* Remove margins and padding from the parent ul */
#myUL {
    margin: 0;
    padding: 0;
}

/* Style the caret/arrow */
.caret {
    cursor: pointer;
    user-select: none; /* Prevent text selection */
    background: red;
}

/* Create the caret/arrow with a unicode, and style it */
.caret::before {
    content: "\25B6";
    color: black;
    display: inline-block;
    margin-right: 6px;
}

/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.caret-down::before {
    transform: rotate(90deg);
}

/* Hide the nested list */
.nested {
    display: none;
}

/* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
.active {
    display: block;
}

【讨论】:

【解决方案3】:

我也在寻找类似的功能。 开发了一个完全可定制的轻量级树生成器组件。

您可以传递自定义子组件和父组件以获得更好的视图

对搜索相同内容的用户很有帮助。

https://www.npmjs.com/package/react-custom-tree

【讨论】:

    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2016-11-02
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多