在传输组件的两面都具有树结构 [英] Having a tree structure on both sides of the Transfer component

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

问题描述

我正在使用 antd的Transfer 组件.使用文档中给出的示例,我能够创建一个类似于以下内容的树形转移盒:

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:

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

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.

沙盒示例中给出的代码如下:

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.

  • 我希望能够转移孩子们
  • 转移孩子时,左表应将剩余的孩子置于父项之下,右表应将其转移的孩子置于父项之下.

推荐答案

查看此示例其中:

  • TransferTree是检查节点并显示树路径的示例.
  • AntdTreeTransfer具有传输时树路径的Transfer组件的示例.
  • 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>
  );
}

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

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