在 Transfer 组件的两边都有一个树结构 [英] Having a tree structure on both sides of the Transfer component

查看:66
本文介绍了在 Transfer 组件的两边都有一个树结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用

有没有办法在右侧也有一个树结构?目前,当我在 0-1 下选择 0-1-0 时,它在右侧显示为平的.

解决方案

查看此

export const renderTreeNodes = data =>data.map(item =>item.children ?(<Tree.TreeNode title={item.title} key={item.key} dataRef={item}>{renderTreeNodes(item.children)}</Tree.TreeNode>) : (<Tree.TreeNode {...item} dataRef={item}/>));export const filterTree = (keys, halfKeys, rootNode) =>根节点?根节点.filter(node => keys.includes(node.key) || halfKeys.includes(node.key)).map(nodeRoot => ({...节点根,孩子:filterTree(键,halfKeys,nodeRoot.children)})): [];导出默认函数 TreeTransfer() {const [checkedNodes, setCheckedNodes] = useState([]);const onCheck = (selectedKeys, info) =>{constfilteredTree = filterTree(selectedKeys, info.halfCheckedKeys, data);setCheckedNodes(filteredTree);};返回 (<FlexBox><Row type="flex" gutter={20}><Col><卡片><Tree checkable defaultExpandAll onCheck={onCheck}>{renderTreeNodes(data)}</树></卡片></Col><Col><卡片><树可检查 defaultExpandAll>{renderTreeNodes(checkedNodes)}</树></卡片></Col></行></FlexBox>);}导出默认函数 AntdTreeTransfer() {const [leftCheckedKeys, setLeftCheckedKeys] = useState([]);const [checkedNodes, setCheckedNodes] = useState([]);const [targetNodes, setTargetNodes] = useState([]);返回 (<FlexBox><转移操作={['', '清除']}onChange={(_, 方向) =>{setLeftCheckedKeys([]);方向 === '正确'?setTargetNodes(checkedNodes): setTargetNodes([]);}}样式={{ 宽度:'50vh' }}>{({ 方向,onItemSelect,selectedKeys }) =>方向 === '左' ?(<树显示线块节点可检查的默认展开全部checkedKeys={leftCheckedKeys}onCheck={(selectedKeys, info) =>{setLeftCheckedKeys(selectedKeys);const 过滤树 = 过滤树(选定的键,info.halfCheckedKeys,数据);setCheckedNodes(filteredTree);const eventKey = info.no​​de.props.eventKey;onItemSelect(eventKey, selectedKeys.includes(eventKey));}}>{renderTreeNodes(data)}</树>) : (<树自动扩展父级块节点可检查的onCheck={(selectedKeys, info) =>{const eventKey = info.no​​de.props.eventKey;onItemSelect(eventKey, selectedKeys.includes(eventKey));}}>{renderTreeNodes(targetNodes)}</树>)}</转移></FlexBox>);}

I am using antd's Transfer component. Using the examples given in the documentation, I am able to create a tree transfer box that looks similar to:

Is there a way I could have a tree structure also on the right side? Currently, as I select 0-1-0 under 0-1, it appears flat on the right side.

The code as also given in the Sandbox example, is given below:

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Transfer, Tree } from 'antd';

const { TreeNode } = Tree;

// Customize Table Transfer
const isChecked = (selectedKeys, eventKey) => {
    return selectedKeys.indexOf(eventKey) !== -1;
};

const generateTree = (treeNodes = [], checkedKeys = []) => {
    return treeNodes.map(({ children, ...props }) => (
        <TreeNode {...props} disabled={checkedKeys.includes(props.key)}>
        {generateTree(children, checkedKeys)}
        </TreeNode>
    ));
};

const TreeTransfer = ({ dataSource, targetKeys, ...restProps }) => {
    const transferDataSource = [];
    function flatten(list = []) {
        list.forEach(item => {
        transferDataSource.push(item);
        flatten(item.children);
        });
    }
    flatten(dataSource);

    return (
        <Transfer
        {...restProps}
        targetKeys={targetKeys}
        dataSource={transferDataSource}
        className="tree-transfer"
        render={item => item.title}
        showSelectAll={false}
        >
        {({ direction, onItemSelect, selectedKeys }) => {
            if (direction === 'left') {
            const checkedKeys = [...selectedKeys, ...targetKeys];
            return (
                <Tree
                blockNode
                checkable
                checkStrictly
                defaultExpandAll
                checkedKeys={checkedKeys}
                onCheck={(
                    _,
                    {
                    node: {
                        props: { eventKey },
                    },
                    },
                ) => {
                    onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
                }}
                onSelect={(
                    _,
                    {
                    node: {
                        props: { eventKey },
                    },
                    },
                ) => {
                    onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
                }}
                >
                {generateTree(dataSource, targetKeys)}
                </Tree>
            );
            }
        }}
        </Transfer>
    );
};

const treeData = [
    { key: '0-0', title: '0-0' },
    {
        key: '0-1',
        title: '0-1',
        children: [{ key: '0-1-0', title: '0-1-0' }, { key: '0-1-1', title: '0-1-1' }],
    },
    { key: '0-2', title: '0-3' },
];

class App extends React.Component {
    state = {
        targetKeys: [],
    };

    onChange = targetKeys => {
        console.log('Target Keys:', targetKeys);
        this.setState({ targetKeys });
    };

    render() {
        const { targetKeys } = this.state;
        return (
        <div>
            <TreeTransfer dataSource={treeData} targetKeys={targetKeys} onChange={this.onChange} />
        </div>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('container'));

The way I want to transfer is depicted in the images below.

  • I want to be able to transfer the children
  • When a child is transferred the left table should have the remaining children under it parent and the right table should have the transferred children under it parent name.

解决方案

Check out this example where:

  • TransferTree is an example of checking nodes and showing the tree path.
  • AntdTreeTransfer an example for Transfer component with tree path on transfer.

export const renderTreeNodes = data =>
  data.map(item =>
    item.children ? (
      <Tree.TreeNode title={item.title} key={item.key} dataRef={item}>
        {renderTreeNodes(item.children)}
      </Tree.TreeNode>
    ) : (
      <Tree.TreeNode {...item} dataRef={item} />
    )
  );

export const filterTree = (keys, halfKeys, rootNode) =>
  rootNode
    ? rootNode
        .filter(node => keys.includes(node.key) || halfKeys.includes(node.key))
        .map(nodeRoot => ({
          ...nodeRoot,
          children: filterTree(keys, halfKeys, nodeRoot.children)
        }))
    : [];

export default function TreeTransfer() {
  const [checkedNodes, setCheckedNodes] = useState([]);

  const onCheck = (selectedKeys, info) => {
    const filteredTree = filterTree(selectedKeys, info.halfCheckedKeys, data);
    setCheckedNodes(filteredTree);
  };

  return (
    <FlexBox>
      <Row type="flex" gutter={20}>
        <Col>
          <Card>
            <Tree checkable defaultExpandAll onCheck={onCheck}>
              {renderTreeNodes(data)}
            </Tree>
          </Card>
        </Col>
        <Col>
          <Card>
            <Tree checkable defaultExpandAll>
              {renderTreeNodes(checkedNodes)}
            </Tree>
          </Card>
        </Col>
      </Row>
    </FlexBox>
  );
}

export default function AntdTreeTransfer() {
  const [leftCheckedKeys, setLeftCheckedKeys] = useState([]);
  const [checkedNodes, setCheckedNodes] = useState([]);
  const [targetNodes, setTargetNodes] = useState([]);

  return (
    <FlexBox>
      <Transfer
        operations={['', 'Clear']}
        onChange={(_, direction) => {
          setLeftCheckedKeys([]);

          direction === 'right'
            ? setTargetNodes(checkedNodes)
            : setTargetNodes([]);
        }}
        style={{ width: '50vh' }}
      >
        {({ direction, onItemSelect, selectedKeys }) =>
          direction === 'left' ? (
            <Tree
              showLine
              blockNode
              checkable
              defaultExpandAll
              checkedKeys={leftCheckedKeys}
              onCheck={(selectedKeys, info) => {
                setLeftCheckedKeys(selectedKeys);
                const filteredTree = filterTree(
                  selectedKeys,
                  info.halfCheckedKeys,
                  data
                );
                setCheckedNodes(filteredTree);

                const eventKey = info.node.props.eventKey;
                onItemSelect(eventKey, selectedKeys.includes(eventKey));
              }}
            >
              {renderTreeNodes(data)}
            </Tree>
          ) : (
            <Tree
              autoExpandParent
              blockNode
              checkable
              onCheck={(selectedKeys, info) => {
                const eventKey = info.node.props.eventKey;
                onItemSelect(eventKey, selectedKeys.includes(eventKey));
              }}
            >
              {renderTreeNodes(targetNodes)}
            </Tree>
          )
        }
      </Transfer>
    </FlexBox>
  );
}

这篇关于在 Transfer 组件的两边都有一个树结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆