React+antd4.9造一个Cascader级联选择轮子

2021-01-06  本文已影响0人  甘道夫老矣

级联选择获取数据功能,两种方案,一种是搜索的级联,一种是回填的级联,不同的用途 方法也不一样,回填的方法建议做缓存处理

image.png

数据结构:键值名称支持自定义

import React, { Component } from "react";
import { Cascader, Card, Row, Col, Form, Spin, Button } from "antd";

import * as service from "../services/test.service";

export default class Test extends Component {
    formRef = React.createRef();
    constructor(props) {
        super(props);
        this.state = {
            bigCategory: [],
            defaultAssetType: [],
            loading: false,

            //登记存储
            path: null,
            assetType: [],
        };
    }

    async componentDidMount() {
        //不需要回填用这个
        // this.createGetAssetType();
        //需要回填用这个
        this.arginAssetType();
    }

    //需要回填获取资产分类
    arginAssetType = async () => {
        let res = await service.getAssetTypeAll();

        let arr = res.result.data.nodes;

        //处理物品类别数据
        let endDataTypeData = this.changeAssetTypeData(arr);
        // //模拟默认数据
        let defaultAsset = [
            { caName: "通用设备", caFaid: null, caAsid: "2000000", isLeaf: false, loading: false },
            { caName: "计算机设备及软件", caFaid: "2000000", caAsid: "2010000", isLeaf: false, loading: false },
            { caName: "计算机设备", caFaid: "2010000", caAsid: "2010100", isLeaf: false, loading: false },
            { caName: "巨/大/中型机", caFaid: "2010100", caAsid: "2010101", isLeaf: true },
        ];
        let AssetTypeArr = [];
        defaultAsset.forEach((item, index) => {
            AssetTypeArr.push(item.caAsid);
        });
        this.setState({
            defaultAssetType: AssetTypeArr,
            bigCategory: endDataTypeData,
            loading: true,
        });
    };
    //处理分类类别数据
    changeAssetTypeData = (val) => {
        val.forEach((item, index) => {
            if (item.children instanceof Object) {
                item.children = item.children.nodes;
                if (item.children.length > 0) {
                    this.changeAssetTypeData(item.children);
                }
            }
        });
        return val;
    };

    //不需要回填获取资产分类
    createGetAssetType = async () => {
        let res = await service.getAssetType();
        if (res === false) return;
        let endData = this.changeAdministrativeCodeHasChildren(res.result.nodes);
        this.setState({
            bigCategory: endData,
        });
    };
    //处理资产分类数据
    changeAdministrativeCodeHasChildren = (value) => {
        value.forEach(async (item) => {
            item.isLeaf = false;
        });
        return value;
    };

    //资产分类级联选择
    onAssetsChange = async (value, valLable) => {
        let path = "";
        //存path
        if (value && value.length > 0) {
            value.forEach((item) => {
                path += item + "-";
            });
        }

        //存完整数据,去掉children的
        let arr = JSON.parse(JSON.stringify(valLable));
        arr.forEach((item, index) => {
            if (item.children) {
                delete item.children;
            }
        });

        //path规则:当前的id+“-”
        this.setState({
            assetType: arr,
            path: path,
        });
    };

    //loading
    loadData = async (value) => {
        // console.log(value);
        const targetOption = value[value.length - 1];
        targetOption.loading = true;
        let res = await service.selectAssetTypeChildren(targetOption.caAsid);
        if (res === false) return (targetOption.loading = false);
        let arr = res.result.nodes;

        if (arr.length > 0) {
            arr.forEach(async (item) => {
                let resChildren = await service.selectAssetTypeChildren(item.caAsid);

                if (resChildren === false) return (targetOption.loading = false);
                if (resChildren.result.nodes.length > 0) {
                    item.isLeaf = false;
                } else {
                    item.isLeaf = true;
                }
            });
        }
        targetOption.loading = false;
        targetOption.children = arr;

        this.setState({
            bigCategory: [...this.state.bigCategory],
        });
    };

    handleSubmitData = (values) => {
        for (let index in values) {
            if (values[index] === undefined) {
                values[index] = "";
            }
        }
        console.log(values);
        //清空表单
        // this.formRef.current.resetFields();
    };

    render() {
        const { bigCategory, defaultAssetType, loading } = this.state;
        console.log(defaultAssetType);
        return loading ? (
            <Row gutter={24}>
                <Col span={8}>
                    <Card title="资产分类的级联选择">
                        <Form
                            onFinish={this.handleSubmitData}
                            ref={this.formRef}
                            initialValues={{
                                assettype: defaultAssetType,
                            }}
                        >
                            <Form.Item label="资产分类" name="assettype">
                                <Cascader
                                    style={{ width: "100%" }}
                                    allowClear
                                    fieldNames={{ label: "caName", value: "caAsid", children: "children" }}
                                    options={bigCategory}
                                    // 新建用loading,回填用showSearch,两个不能同时使用
                                    // loadData={this.loadData}
                                    showSearch={(inputValue, path) => {
                                        return path.some((option) => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
                                    }}
                                    onChange={this.onAssetsChange}
                                    changeOnSelect
                                    placeholder="请选择资产分类"
                                />
                            </Form.Item>
                            <div className="split-draw-btn">
                                <Button type="primary" htmlType="submit">
                                    提交
                                </Button>
                            </div>
                        </Form>
                    </Card>
                </Col>
            </Row>
        ) : (
            <div
                style={{
                    width: "300px",
                    height: "300px",
                    margin: "50px auto",
                    // paddingTop: 50,
                    textAlign: "center",
                }}
            >
                <Spin size="large" />
            </div>
        );
    }
}

上一篇 下一篇

猜你喜欢

热点阅读