【问题标题】:React: How to collapse all the all open children nodes if their parent node is closing?React:如果父节点正在关闭,如何折叠所有打开的子节点?
【发布时间】:2022-11-03 02:19:31
【问题描述】:

我正在使用反应。我能够从 xml 文件生成一棵树。
请找到我的沙盒:https://codesandbox.io/s/shy-snow-nfce4i 请找到所附图片。 该代码在 Visual Studio 中运行良好。我不确定如何使用沙盒,无法理解沙盒错误。

目前,树工作正常。如果其父节点正在折叠,则展开/打开的子节点的折叠/最小化不起作用。

请检查我的代码并查看代码需要更改的地方。

非常感谢。

import React, { Component } from "react";
import ProductsTree from "./ProductsTreeView";
const initialState = {
  currentNode: {},
  data: ""
};
export class App extends Component {
  constructor(props) {
    super(props);
    this.state = initialState;
    this.setCurrentNode = this.setCurrentNode.bind(this);
  }
  setCurrentNode(node) {
    this.setState({ currentNode: node });
  }
  render() {
    return (
      <div>
        <ProductsTree setCurrentNode={this.setCurrentNode} />
      </div>
    );
  }
}
export default App;
______________________________________________________
import React, { Component } from "react";
import axios from "axios";
import XMLParser from "react-xml-parser";
import { Link } from "react-router-dom";
import tree from "./tree.xml";
class ProductsTreeView extends Component {
  render() {
    return (
      <div id="TreeView">
        <TreeView setCurrentNode={this.props.setCurrentNode} />
      </div>
    );
  }
}

class Node {
  description = "n/a";
  id = -1;
  key_id = -1;
  linkpagename = "";
  isActive = false;
  nodes = [];
  constructor(description, id, key_id, linkpagename) {
    this.description = description;
    this.id = id;
    this.key_id = key_id;
    this.linkpagename = linkpagename;
  }

  static nodesFromXml(xml) {
    const map = (entity, nodes) => {
      const id = entity.attributes["id"];
      const key_id = entity.attributes["key-id"];
      const descriptionText =
        entity.children[
          entity.children.findIndex((child) => child.name === "description")
        ].value;
      const entities = entity.children.filter(
        (child) => child.name === "entity"
      );

      var linkPageName = entity.attributes["link-page-name"];
      linkPageName = linkPageName.replace(".aspx", "");
      const node = new Node(descriptionText, id, key_id, linkPageName);
      nodes.push(node);
      entities.forEach((entity) => map(entity, node.nodes));
    };
    const parsedData = new XMLParser().parseFromString(xml);
    const entities = parsedData.children.filter(
      (child) => child.name === "entity"
    );

    const nodes = [];
    entities.forEach((entity) => map(entity, nodes));
    return nodes;
  }
}

class TreeView extends React.Component {
  constructor(props) {
    super(props);
    this.state = { nodes: [] };
    this.toggleNode = this.toggleNode.bind(this);
  }
  componentDidMount() {
    axios
      .get(tree, { "Content-Type": "application/xml; charset=utf-8" })
      .then((response) =>
        this.setState({ nodes: Node.nodesFromXml(response.data) })
      )
      .catch((error) => console.error("Error:", error));
  }
  render() {
    const nodes = this.state.nodes
    return (
      <ul>
        {nodes.map((node) => (
          <TreeNode
            id={node.id}
            key={node.key_id}
            node={node}
            onToggle={this.toggleNode}
            setCurrentNode={this.props.setCurrentNode}
          />
        ))}
      </ul>
    );
  }
  toggleNode(node) {
    this.props.setCurrentNode(node);
    function _toggleNode(currentNode, node) {
      if (currentNode.id === node.id) {
        //currentNode.id === node.id)

        {
          if (currentNode.key_id === node.key_id) {
            currentNode.isActive = !currentNode.isActive;
          }
        }
      } else {
        currentNode.nodes.forEach((childNode) => _toggleNode(childNode, node));
      }
    }
    const nodes = this.state.nodes;
    nodes.forEach((currentNode) => _toggleNode(currentNode, node));
    this.setState((state) => (state.nodes = nodes));
  }
}
class TreeNode extends React.Component {
  render() {
    const node = this.props.node;
    const onToggle = this.props.onToggle;
    let activeChildren = null;
    if (node.isActive && node.nodes.length > 0) {
      activeChildren = (
        <ul>
          {node.nodes.map((node) => (
            <TreeNode
              id={node.id}
              key={node.key_id}
              node={node}
              onToggle={onToggle}
            />
          ))}
        </ul>
      );
    }

    return (
      <li
        id={node.id}
        linkpagename={node.linkpagename}
        key={node.key_id}
        onClick={(event) => {
          event.stopPropagation();
          onToggle(node);
        }}
      >
        <Link
          to={node.linkpagename}
          style={{ textDecoration: "none", color: "#000000" }}
        >[![enter image description here][3]][3]
          {node.description}
        </Link>{" "}
        - {node.key_id} - {node.linkpagename}
        {activeChildren}
      </li>
    );
  }
}
export default ProductsTreeView;

<?xml version="1.0" standalone="yes"?>
<tree>
       <entity id="e11" key-id="1" link-page-name="Add_Category">
              <description>Service</description>
              <image>images/plus.gif</image>
              <imageNode>images/de.gif</imageNode>
              <imageOpen>images/minus.gif</imageOpen>
              <entity id="e248" key-id="48" link-page-name="Edit_Category">
                     <description>A_test1_test1</description>
                     <image>images/plus.gif</image>
                     <imageNode>images/de.gif</imageNode>
                     <imageOpen>images/minus.gif</imageOpen>
                     <entity id="e3717" key-id="717" link-page-name="Edit_Product">
                           <description>A_SubItem1</description>
                           <image>images/plus.gif</image>
                           <imageNode>images/de.gif</imageNode>
                           <imageOpen>images/minus.gif</imageOpen>
                           <entity id="e45546" key-id="5546" link-page-name="Edit_ProdTemplate">
                                  <description>A_Test_Template</description>
                                  <image>images/paper.gif</image>
                                  <imageOpen>images/paper.gif</imageOpen>
                           </entity>
                     </entity>
              </entity>
              <entity id="e247" key-id="47" link-page-name="Edit_Category">
                     <description>A_test6</description>
                     <image>images/plus.gif</image>
                     <imageNode>images/de.gif</imageNode>
                     <imageOpen>images/minus.gif</imageOpen>
                     <entity id="e3716" key-id="716" link-page-name="Edit_Product">
                           <description>A_Item</description>
                           <image>images/plus.gif</image>
                           <imageNode>images/de.gif</imageNode>
                           <imageOpen>images/minus.gif</imageOpen>
                           <entity id="e45545" key-id="5545" link-page-name="Edit_ProdTemplate">
                                  <description>temp1</description>
                                  <image>images/paper.gif</image>

                                  <imageOpen>images/paper.gif</imageOpen>
                           </entity>
                     </entity>
              </entity>
       </entity>

       <entity id="e12" key-id="2" link-page-name="Add_Category">

              <description>Sales</description>

              <image>images/plus.gif</image>

              <imageNode>images/de.gif</imageNode>

              <imageOpen>images/minus.gif</imageOpen>

              <entity id="e230" key-id="30" link-page-name="Edit_Category">

                     <description>Gift Cards</description>

                     <image>images/plus.gif</image>

                     <imageNode>images/de.gif</imageNode>

                     <imageOpen>images/minus.gif</imageOpen>

                     <entity id="e3421" key-id="421" link-page-name="Edit_Product">

                           <description>Sample Card</description>

                           <image>images/plus.gif</image>

                           <imageNode>images/de.gif</imageNode>

                           <imageOpen>images/minus.gif</imageOpen>

                           <entity id="e43308" key-id="3308" link-page-name="Edit_ProdTemplate">

                                  <description>greeting temp</description>

                                  <image>images/paper.gif</image>

                                  <imageOpen>images/paper.gif</imageOpen>

                           </entity>

                     </entity>

                     <entity id="e3422" key-id="422" link-page-name="Edit_Product">

                           <description>De Card</description>

                           <image>images/plus.gif</image>

                           <imageNode>images/de.gif</imageNode>

                           <imageOpen>images/minus.gif</imageOpen>

                           <entity id="e43309" key-id="3309" link-page-name="Edit_ProdTemplate">

                                  <description>NS Temp</description>

                                  <image>images/paper.gif</image>

                                  <imageOpen>images/paper.gif</imageOpen>

                           </entity>

                     </entity>

 

              </entity>

              <entity id="e215" key-id="15" link-page-name="Edit_Category">

                     <description>Chck</description>

                     <image>images/plus.gif</image>

                     <imageNode>images/de.gif</imageNode>

                     <imageOpen>images/minus.gif</imageOpen>

                     <entity id="e3671" key-id="671" link-page-name="Edit_Product">

                           <description>Add item</description>

                           <image>images/plus.gif</image>

                           <imageNode>images/de.gif</imageNode>

                           <imageOpen>images/minus.gif</imageOpen>

                           <entity id="e45438" key-id="5438" link-page-name="Edit_ProdTemplate">

                                  <description>Ahhhh</description>

                                  <image>images/paper.gif</image>

                                  <imageOpen>images/paper.gif</imageOpen>

                           </entity>

                     </entity>

                     <entity id="e3450" key-id="450" link-page-name="Edit_Product">

                           <description>Advtttt</description>

                           <image>images/plus.gif</image>

                           <imageNode>images/de.gif</imageNode>

                           <imageOpen>images/minus.gif</imageOpen>

                           <entity id="e43577" key-id="3577" link-page-name="Edit_ProdTemplate">

                                  <description>gggggg</description>

                                  <image>images/paper.gif</image>

                                  <imageOpen>images/paper.gif</imageOpen>

                           </entity>

                     </entity>

              </entity>

 

       </entity>

</tree>

【问题讨论】:

  • 尝试为您的问题提供一个最小可重复的示例 - 它也可以帮助您找出答案。这对于人们阅读太多代码只是为了找到与您的问题有关的部分。

标签: javascript reactjs


【解决方案1】:

更新toggleNode 处理程序的内部_toggleNode 函数以获取第三个参数,我们将其称为isActive,如果设置为任何未定义的值,则将当前节点的isActive 属性设置为值,否则进行正常的节点切换。添加一个额外的检查,如果节点是只是切换为非活动以递归节点的子树并传递一个 isActive 值为 false 以停用该子树中的所有节点。

toggleNode(node) {
  const { nodes } = this.state;
  this.props.setCurrentNode(node);

  function _toggleNode(currentNode, node, isActive) {
    if (isActive !== undefined) {
      currentNode.isActive = isActive;
    } else if (currentNode.id === node.id) {
      if (currentNode.key_id === node.key_id) {
        currentNode.isActive = !currentNode.isActive;
      }
    }
    currentNode.nodes.forEach((childNode) =>
      _toggleNode(childNode, node, currentNode.isActive ? undefined : false)
    );
  }

  nodes.forEach((currentNode) => _toggleNode(currentNode, node));

  this.setState((state) => (state.nodes = nodes));
}

【讨论】:

  • 非常感谢 Drew 帮助我找到解决方案。我会仔细看看的。非常感谢您的帮助。
  • 谢谢德鲁。展开/折叠节点功能工作正常。我添加了两个链接 ExpandAll 和 CollapseAll。如何传递 isActive 以便 ExpandAll 链接在节点折叠时展开所有节点。如果节点展开,CollapseAll 链接将折叠所有节点。
  • 谢谢德鲁。折叠/展开节点工作正常。我添加了两个链接 ExpandAll 和 CollapseAll。 ExpandAll 链接展开所有节点如果节点折叠,折叠所有折叠的所有节点。如何通过isActive?再次感谢
  • 嗨 Drew,我在 App.js 中添加了两个链接。如何通过isActive true 和false 使用expand 和collapse 函数来展开所有节点或折叠所有节点。 <Link onClick={() => {this.ExpandAll(); }}><b>展开</b></Link> <Link onClick={() => {this.CollapseAll(); }}><b>最小化</b></Link>
  • 嗨 Drew,请帮助我修复树节点图标。在折叠的情况下显示加号图标,在展开的情况下显示减号。请找到沙盒:codesandbox.io/s/shy-snow-nfce4i。图标正在显示,但它显示的是圆形项目符号。如何更换圆形子弹。即使节点没有孩子,也总是需要显示加号图标。单击仅节点图标将变为减号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多